{"record":{"id":"114918b91b62afc0","repo":"elsa-workflows/elsa-core","slug":"variable-foreach-variablename-is-not-declared-use-var","errorCode":null,"errorMessage":"Variable '{forEach.VariableName}' is not declared. Use 'var {forEach.VariableName}' to declare a new variable in the foreach loop.","messagePattern":"Variable '(.+?)' is not declared\\. Use 'var (.+?)' to declare a new variable in the foreach loop\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Dsl.ElsaScript/Compiler/ElsaScriptCompiler.cs","lineNumber":277,"sourceCode":"        };\n    }\n\n    private async Task<IActivity> CompileForEachAsync(ForEachNode forEach, CancellationToken cancellationToken = default)\n    {\n        Variable loopVariable;\n\n        if (forEach.DeclaresVariable)\n        {\n            // Create a new loop variable\n            loopVariable = new Variable<object>(forEach.VariableName, null!);\n            _variables[forEach.VariableName] = loopVariable;\n        }\n        else\n        {\n            // Reuse existing variable\n            if (!_variables.TryGetValue(forEach.VariableName, out loopVariable!))\n            {\n                throw new InvalidOperationException($\"Variable '{forEach.VariableName}' is not declared. Use 'var {forEach.VariableName}' to declare a new variable in the foreach loop.\");\n            }\n        }\n\n        var items = CompileExpressionAsInput<ICollection<object>>(forEach.Collection);\n        var body = await CompileStatementAsync(forEach.Body, cancellationToken);\n\n        var forEachActivity = new ForEach<object>(items)\n        {\n            CurrentValue = new(loopVariable),\n            Body = body\n        };\n\n        return forEachActivity;\n    }\n\n    private async Task<IActivity> CompileForAsync(ForNode forNode, CancellationToken cancellationToken = default)\n    {\n        Variable loopVariable;","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Dsl.ElsaScript/Compiler/ElsaScriptCompiler.cs#L259-L295","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nforeach (item in items) { } // item never declared\n// after\nvar item;\nforeach (item in items) { }","handlingStrategy":"validation","validationCode":"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(', '));","typeGuard":"function forEachVarsDeclared(ast) { const declared = declaredVarNames(ast); return ast.forEachNodes.every(n => declared.has(n.variableName)); }","tryCatchPattern":"try { await compileScript(script); } catch (InvalidOperationException ex) when (ex.Message.Contains('is not declared')) { showDeclareVarFix(ex); }","preventionTips":["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."],"tags":["dsl","variables","compiler"],"backgroundTag":"missing-required-argument","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}