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
- Guard the call: only create when the variable does not already exist locally, otherwise set its value.
- Use SetVariable (memory.Set / variable.Set semantics) to assign to an existing variable instead of CreateVariable.
- Rename the variable to be unique per scope or declare it once in the enclosing workflow/composite.
- 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
- Check existence before CreateVariable; use SetVariable for assignment
- Give script-created variables unique names per scope
- Ensure variable-creation code does not re-run on bookmark resumption
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
- C# workflow expression execution is disabled. Set…
- Could not find an expression descriptor for expression type
- Could not find an expression descriptor for expression type
- No parent variable container found
- Activity descriptor not found
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)