elsa-workflows/elsa-core · error · InvalidOperationException
Variable ' ' is not declared. Use 'var ' to declare a new…
Error message
Variable '{forEach.VariableName}' is not declared. Use 'var {forEach.VariableName}' to declare a new variable in the foreach loop. What it means
CompileForEachAsync reuses an existing declared variable as the foreach loop variable; if the script's foreach names a variable never declared with 'var', the compiler throws InvalidOperationException with a message suggesting how to declare it. ElsaScript requires loop variables to be declared before reuse in foreach.
Solutions
- Declare the variable first: var item; then foreach (item in collection) { ... }.
- Match the declared variable name exactly (case-sensitive).
- If your script version supports inline declaration, use the foreach syntax that declares the variable.
- Catch the exception and show a fix-it hint pointing at the missing 'var' declaration.
Example fix
// before
foreach (item in items) { } // item never declared
// after
var item;
foreach (item in items) { } Defensive patterns
Strategy: validation
Validate before calling
const declared = collectVarDeclarations(ast); const missing = collectForEachVars(ast).filter(v => !declared.has(v.name)); if (missing.length) throw new Error('Declare with var: ' + missing.map(m => m.name).join(', ')); Type guard
function forEachVarsDeclared(ast) { const declared = declaredVarNames(ast); return ast.forEachNodes.every(n => declared.has(n.variableName)); } Try / catch
try { await compileScript(script); } catch (InvalidOperationException ex) when (ex.Message.Contains('is not declared')) { showDeclareVarFix(ex); } Prevention
- Declare loop variables with 'var' before foreach/for statements.
- Use a linter that walks the AST checking variable declarations before use.
- Keep variable names consistent (case-sensitive) between declaration and loop.
When it happens
Trigger: A foreach statement whose VariableName is not a key in the compiler's _variables dictionary — i.e. the script does not declare the loop variable with 'var' before the foreach.
Common situations: Scripts copied from C# habits where foreach implicitly declares its variable, typos between the 'var' declaration and the foreach variable name, or variable declared in a sibling scope not visible to the compiler.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Variable ' ' is not declared. Use 'var ' to declare a new…
- Statement type is not supported
- Activity ' ' not found in registry
- Property ' ' not found on activity type
- Source label ' ' not found in flowchart
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/114918b91b62afc0.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Dsl.ElsaScript/Compiler/ElsaScriptCompiler.cs:277
};
}
private async Task<IActivity> CompileForEachAsync(ForEachNode forEach, CancellationToken cancellationToken = default)
{
Variable loopVariable;
if (forEach.DeclaresVariable)
{
// Create a new loop variable
loopVariable = new Variable<object>(forEach.VariableName, null!);
_variables[forEach.VariableName] = loopVariable;
}
else
{
// Reuse existing variable
if (!_variables.TryGetValue(forEach.VariableName, out loopVariable!))
{
throw new InvalidOperationException($"Variable '{forEach.VariableName}' is not declared. Use 'var {forEach.VariableName}' to declare a new variable in the foreach loop.");
}
}
var items = CompileExpressionAsInput<ICollection<object>>(forEach.Collection);
var body = await CompileStatementAsync(forEach.Body, cancellationToken);
var forEachActivity = new ForEach<object>(items)
{
CurrentValue = new(loopVariable),
Body = body
};
return forEachActivity;
}
private async Task<IActivity> CompileForAsync(ForNode forNode, CancellationToken cancellationToken = default)
{
Variable loopVariable;View on GitHub (pinned to fe9217bdfa)