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

  1. Declare the variable first: var item; then foreach (item in collection) { ... }.
  2. Match the declared variable name exactly (case-sensitive).
  3. If your script version supports inline declaration, use the foreach syntax that declares the variable.
  4. 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

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


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)