elsa-workflows/elsa-core · error · Exception

Variable already exists in the context.

Error message

Variable {name} already exists in the context.

What it means

CreateVariable on ExpressionExecutionContext creates a brand-new variable in the current (local) memory scope. If a variable with the same name already exists in that local scope, creating it again would silently shadow or corrupt state, so the extension throws this exception. Use SetVariable semantics instead when overwriting is intended.

Solutions

  1. Guard the call: only create when the variable does not already exist locally, otherwise set its value.
  2. Use SetVariable (memory.Set / variable.Set semantics) to assign to an existing variable instead of CreateVariable.
  3. Rename the variable to be unique per scope or declare it once in the enclosing workflow/composite.
  4. Wrap creation logic so it executes only once (e.g. first-visit check via `context.GetIsTriggeredByBookmark` or similar first-execution checks).

Example fix

// before
context.CreateVariable("total", 0); // throws if 'total' exists in local scope
// after
if (context.GetVariable("total", localScopeOnly: true) == null)
    context.CreateVariable("total", 0);
else
    context.SetVariable("total", 0);
Defensive patterns

Strategy: validation

Validate before calling

if (context.GetVariable(name, localScopeOnly: true) != null)
    throw new InvalidOperationException($"Variable '{name}' already exists; use SetVariable to assign");

Type guard

bool exists = context.GetVariable(name, localScopeOnly: true) != null;

Try / catch

try { context.CreateVariable(name, value); } catch (Exception ex) { logger.LogError(ex, "Variable {Name} already declared in local scope", name); }

Prevention

When it happens

Trigger: Calling expressionExecutionContext.CreateVariable<T>(name, ...) when context.GetVariable(name, localScopeOnly: true) already returns a value — i.e. the name is already declared in the current memory scope.

Common situations: Re-running an expression/script block that creates variables on each pass without checking existence; two script activities in the same scope declaring the same variable name; workflow retries or bookmark resumption re-executing the creation code path.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/d4d0891d50f628da. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs:158

            foreach (var block in context.Memory.Blocks.Where(b => b.Value.Metadata is VariableBlockMetadata))
            {
                var metadata = block.Value.Metadata as VariableBlockMetadata;
                if (metadata!.Variable.Name == name)
                    return block.Value;
            }

            return localScopeOnly ? null : context.ParentContext?.GetVariableBlock(name);
        }

        /// <summary>
        /// Creates a named variable in the context.
        /// </summary>
        public Variable CreateVariable<T>(string name, T? value, Type? storageDriverType = null, Action<MemoryBlock>? configure = null)
        {
            var existingVariable = context.GetVariable(name, localScopeOnly: true);

            if (existingVariable != null)
                throw new($"Variable {name} already exists in the context.");

            var variable = new Variable(name, value)
            {
                StorageDriverType = storageDriverType ?? typeof(WorkflowInstanceStorageDriver)
            };
        
            var parsedValue = variable.ParseValue(value);

            // Find the first parent context that has a variable container.
            // If not found, use the current context.
            var variableContainerContext = context.GetVariableContainerContext();

            variableContainerContext.Set(variable, parsedValue, configure);
            return variable;
        }

        /// <summary>
        /// Returns the first parent context that contains a variable container.

View on GitHub (pinned to fe9217bdfa)