elsa-workflows/elsa-core · error · InvalidOperationException
Variable ' ' is not declared. Use 'var ' to declare a new…
Error message
Variable '{forNode.VariableName}' is not declared. Use 'var {forNode.VariableName}' to declare a new variable in the for loop. What it means
CompileForAsync reuses an existing declared variable as the for-loop counter; if forNode.VariableName was never declared with 'var', the compiler throws InvalidOperationException with a message suggesting the 'var' declaration. Like foreach, the for statement does not implicitly declare its loop variable.
Solutions
- Declare the counter before the loop: var i; then for (i = 0; i < 10; i += 1) { ... }.
- Ensure the declared name matches the loop variable exactly.
- If the parser supports an inline declaration form, use it so the variable is created by the loop itself.
- Catch the exception and surface a hint to declare the loop variable.
Example fix
// before
for (i = 0; i < 10; i += 1) { } // i undeclared
// after
var i;
for (i = 0; i < 10; i += 1) { } Defensive patterns
Strategy: validation
Validate before calling
const declared = collectVarDeclarations(ast); const missing = collectForVars(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 forVarsDeclared(ast) { const declared = declaredVarNames(ast); return ast.forNodes.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
- Always emit 'var i;' before for loops when generating scripts.
- Lint for undeclared identifiers before compilation.
- Avoid C-style implicit declarations; ElsaScript requires explicit 'var'.
When it happens
Trigger: A for statement whose VariableName is absent from the compiler's _variables dictionary when the 'else' reuse path is taken (no inline declaration provided).
Common situations: C-style habits (for (i = 0; ...)) without declaring i, a typo between declaration and loop usage, or the variable declared in an enclosing scope the compiler's variable table does not include.
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/4409832110dc5c0d.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Dsl.ElsaScript/Compiler/ElsaScriptCompiler.cs:308
return forEachActivity;
}
private async Task<IActivity> CompileForAsync(ForNode forNode, CancellationToken cancellationToken = default)
{
Variable loopVariable;
if (forNode.DeclaresVariable)
{
// Create a new loop variable
loopVariable = new Variable<int>(forNode.VariableName, 0);
_variables[forNode.VariableName] = loopVariable;
}
else
{
// Reuse existing variable
if (!_variables.TryGetValue(forNode.VariableName, out loopVariable!))
{
throw new InvalidOperationException($"Variable '{forNode.VariableName}' is not declared. Use 'var {forNode.VariableName}' to declare a new variable in the for loop.");
}
}
var start = CompileExpressionAsInput<int>(forNode.Start);
var end = CompileExpressionAsInput<int>(forNode.End);
var step = CompileExpressionAsInput<int>(forNode.Step);
var body = await CompileStatementAsync(forNode.Body, cancellationToken);
var forActivity = new For
{
Start = start,
End = end,
Step = step,
OuterBoundInclusive = new Input<bool>(forNode.IsInclusive),
CurrentValue = new Output<object?>(loopVariable),
Body = body
};
View on GitHub (pinned to fe9217bdfa)