OctopusDeploy / Issues

| Public | Bug reports and known issues for Octopus Deploy and all related tools
https://octopus.com
162 stars 20 forks source link

Unable to run a runbook using 2 prompted variable values for a variable, one being unscoped - error 'An item with the same key has already been added. Key: xxxx' #8481

Closed Clare-Octopus closed 3 months ago

Clare-Octopus commented 11 months ago

Severity

Blocking customers from running that runbook, a workaround exists

Version

2023.3.13159, 2024.1.1234-hotfix.1457

Latest Version

I could reproduce the problem in the latest build

What happened?

If you have multiple variable values for a variable name, two bring prompted and one of those prompted variables being unscoped:

image

And you go to run a runbook with one of those variables included in the process for the runbook, the runbook run errors out with 'An item with the same key has already been added. Key: xxxx' when running the runbook (you need to make sure you are running it to the same environment as the prompted scoped variable - Production in my example below)

image

The exact same setup works for a deployment, just not a runbook.

Its almost like the runbook is trying to use the Variable name rather than the Variable value and is erroring out because it is the same Key for both.

Reproduction

  1. Create a project and create a variable, set it up like in my first screenshot in the 'What Happened' section, ensure you have two prompted variables, one scoped to an environment and one unscoped.

  2. Create a runbook and have a Run A Script step in the process and include this in your script - Write-Host "$VariableName" ie Write-Host "$DatabaseName".

  3. Publish the runbook and run it, ensure you select one of the environments that one of the prompted variable values is scoped to.

  4. Run the runbook and you will see the error 'An item with the same key has already been added. Key: xxxx'.

  5. Follow the same process to create a deployment (add a run a script step with the write host command) run that deployment to the same environment as above and you will see it deploy with no errors.

Error and Stacktrace

2023-11-17 17:09:25.3782   4024    315  INFO  "HTTP" "POST" to "192.168.0.201""/api/Spaces-1/runbookRuns" "completed" with 400 in 00:00:00.0373601 (37ms) by "octoadmin"
System.ArgumentException: An item with the same key has already been added. Key: DatabaseName
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at Octopus.Core.Features.Variables.VariableParser.get_InScopePromptedVariableMap() in ./source/Octopus.Core/Features/Variables/VariableParser.cs:line 28
   at Octopus.Core.Features.Variables.VariableParser.<>c__DisplayClass12_0.<ParseVariables>b__0(String key) in ./source/Octopus.Core/Features/Variables/VariableParser.cs:line 38
   at System.Linq.Enumerable.SelectArrayIterator`2.MoveNext()
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at Octopus.Core.Features.Variables.VariableParser.ParseVariables(IReadOnlyDictionary`2 variables) in ./source/Octopus.Core/Features/Variables/VariableParser.cs:line 38
   at Octopus.Core.Features.Runbooks.RunbookRunResourceFactory.TryResolvePromptedVariablesByNameOrId(RunbookSnapshot snapshot, DeploymentEnvironmentId environmentId, RunbookId runbookId, IReadOnlyDictionary`2 userProvidedVariables) in ./source/Octopus.Core/Features/Runbooks/RunbookRunResourceFactory.cs:line 161
   at Octopus.Core.Features.Runbooks.RunbookRunResourceFactory.CreateRunbookRunResource(RunRunbookCommandV1 command, String snapshotNameOrId, ProjectId projectId, DeploymentEnvironmentId environmentId, SpaceId spaceId, TenantId tenantId) in ./source/Octopus.Core/Features/Runbooks/RunbookRunResourceFactory.cs:line 113
   at Octopus.Core.Features.Runbooks.RunbookRunResourceFactory.<>c__DisplayClass7_0.<CreateRunsFor>b__0(DeploymentEnvironmentId env) in ./source/Octopus.Core/Features/Runbooks/RunbookRunResourceFactory.cs:line 96
   at System.Linq.Enumerable.SelectArrayIterator`2.MoveNext()
   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
   at Octopus.Core.Features.Runbooks.RunbookRunResourceFactory.CreateRunsFor(RunRunbookCommandV1 command, Runbook runbook) in ./source/Octopus.Core/Features/Runbooks/RunbookRunResourceFactory.cs:line 96
   at Octopus.Server.Web.Handlers.RunRunbookCommandV1Handler.Handle(RunRunbookCommandV1 command, CancellationToken cancellationToken) in ./source/Octopus.Server/Web/Handlers/RunRunbookCommandV1Handler.cs:line 103
   at Octopus.Core.Infrastructure.Mediator.AutofacMediator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/AutofacMediator.cs:line 28
   at Octopus.Core.Infrastructure.Mediator.Decorators.SystemComponentModelValidationDecorator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/Decorators/SystemComponentModelValidationDecorator.cs:line 40
   at Octopus.Core.Infrastructure.Mediator.Decorators.FluentValidationsDecorator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/Decorators/FluentValidationsDecorator.cs:line 51
   at Octopus.Core.Infrastructure.Mediator.Decorators.MessageBusSiphoningDecorator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/Decorators/MessageBusSiphoningDecorator.cs:line 32
   at Octopus.Core.Features.Runbooks.CreateRunbookRunCommandHandler.Handle(CreateRunbookRunCommand command, CancellationToken cancellationToken) in ./source/Octopus.Core/Features/Runbooks/CreateRunbookRunCommandHandler.cs:line 49
   at Octopus.Core.Infrastructure.Mediator.AutofacMediator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/AutofacMediator.cs:line 28
   at Octopus.Core.Infrastructure.Mediator.Decorators.SystemComponentModelValidationDecorator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/Decorators/SystemComponentModelValidationDecorator.cs:line 40
   at Octopus.Core.Infrastructure.Mediator.Decorators.FluentValidationsDecorator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/Decorators/FluentValidationsDecorator.cs:line 51
   at Octopus.Core.Infrastructure.Mediator.Decorators.MessageBusSiphoningDecorator.Do[TCommand,TResponse](ICommand`2 command, CancellationToken cancellationToken) in ./source/Octopus.Core/Infrastructure/Mediator/Decorators/MessageBusSiphoningDecorator.cs:line 32
   at Octopus.Server.Web.Controllers.RunbookRuns.CreateRunbookRunController.CreateRunbookRun(CreateRunbookRunCommand command, CancellationToken cancellationToken) in ./source/Octopus.Server/Web/Controllers/RunbookRuns/CreateRunbookRunController.cs:line 26
   at lambda_method3868289(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Octopus.Server.Web.Middleware.BoundaryTrailerRewriteMiddleware.Invoke(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/BoundaryTrailerRewriteMiddleware.cs:line 44
   at Octopus.Server.Web.Infrastructure.Authentication.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) in ./source/Octopus.Server/Web/Infrastructure/Authentication/AuthorizationMiddlewareResultHandler.cs:line 50
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 46
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 46
   at Octopus.Server.Web.Middleware.OctopusClientOldVersionWarningMiddleware.InvokeAsync(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/OctopusClientOldVersionWarningMiddleware.cs:line 51
   at Octopus.Server.Web.Middleware.DynamicContentHeadersMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/DynamicContentHeadersMiddleware.cs:line 50
   at Octopus.Server.Web.Middleware.MaintenanceModeMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/MaintenanceModeMiddleware.cs:line 59
   at Octopus.Server.Web.Middleware.OctopusAuthenticationMiddleware.InvokeAsync(HttpContext context, IUserAuthenticator userAuthenticator, IAuthCookieService authCookieService, IWebAuthCache authCache, ILogger logger) in ./source/Octopus.Server/Web/Middleware/OctopusAuthenticationMiddleware.cs:line 59
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.Middleware.LegacyRequestLoggerMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/LegacyRequestLoggerMiddleware.cs:line 44
   at Octopus.Server.Web.Middleware.TelemetryMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/TelemetryMiddleware.cs:line 65
   at Octopus.Server.Web.Middleware.ErrorHandlingMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/ErrorHandlingMiddleware.cs:line 50
2023-11-17 17:09:25.3782   4024    315  INFO  "HTTP" "POST" to "192.168.0.201""/bff/telemetry/recordPortalOperation" "completed" with 200 in 00:00:00.0111217 (11ms) by "octoadmin"

More Information

Internal Ticket - https://octopus.zendesk.com/agent/tickets/160799

Workaround

You will need to separate out the unscoped prompted variable and give it its own individual variable name as shown below, this will allow you to run the runbook, you will need to change any scripts you are using or process steps in the runbook to account for the new variable name and value:

image

octoreleasebot commented 3 months ago

Release Note: Fix a bug where runbooks runs are blocked from being created if there are multiple prompted variable values for the same variable

Octobob commented 1 month ago

:tada: The fix for this issue has been released in:

Release stream Release
2024.3 2024.3.7513
2024.4+ all releases