xai-org/x-algorithm · error · SemanticCheckFailure
variable %s not defined
Error message
variable %s not defined
What it means
getVariable walks the scope chain looking for a binding of the given name and throws if no scope defines it. This is the classic 'unresolved identifier' error of the BotMaker DSL compiler.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/compiler/CompilerContext.java:279
CompilerScope currentScope = scopeList.getFirst();
Parameter parameter = Parameter.variable(variableName, returnType, astNode);
currentScope.defineVariable(parameter);
}
void defineVariable(
String variableName,
ASTNode astNode) throws SemanticCheckFailure {
defineVariable(variableName, astNode.getReturnType(), astNode);
}
Variable getVariable(String variableText) throws SemanticCheckFailure {
for (CompilerScope scope : scopeList) {
if (scope.isVariableDefined(variableText)) {
Parameter parameter = scope.getVariable(variableText);
return new Variable(variableText, parameter);
}
}
throw new SemanticCheckFailure(String.format("variable %s not defined", variableText));
}
TypeContext getTypeContext() throws SemanticCheckFailure {
if (scopeList.isEmpty()) {
throw new SemanticCheckFailure("There is no type context");
}
return scopeList.getFirst();
}
void defineType(ThriftType thriftType, String alias) throws SemanticCheckFailure {
if (scopeList.size() <= 1) {
throw new SemanticCheckFailure(
String.format("type cannot defined in root scope: %s", alias));
}
CompilerScope scope = currentScope();
scope.defineType(thriftType, alias);View on GitHub (pinned to 24c60942c5)
Solutions
- Fix the spelling of the variable to match its binder
- Ensure the reference is inside the construct that binds the variable (lambda/forEach/with/val)
- Introduce the variable with a binding form before using it
Example fix
// before filter(x, > 0) // x unbound // after forEach(items, filter(x, x > 0)) // hmm invalid; use binders that exist
Defensive patterns
Strategy: validation
Validate before calling
boolean defined = false;
for (CompilerScope s : scopes) if (s.isVariableDefined(name)) { defined = true; break; }
if (!defined) throw new IllegalArgumentException("undefined variable: " + name); Try / catch
catch (SemanticCheckFailure e) { if (e.getMessage().startsWith("variable") && e.getMessage().endsWith("not defined")) { /* check binders and spelling */ } } Prevention
- Ensure references sit inside the binder's scope (forEach/lambda/with)
- Use distinct, descriptive binder names to avoid typos
When it happens
Trigger: Referencing a variable in an expression that was never introduced by a parameter, lambda binder, val/with binding, or forEach/fold binder — e.g. using 'x' without 'forEach(x, ...)' wrapping it, or a typo in a variable name.
Common situations: Typos in variable names; referencing lambda parameters outside the lambda body; copy-pasting expression fragments that depend on binders defined elsewhere; shadowing/renaming binders during refactors.
Related errors
- Function '%s' does not exist
- Function '%s' does not exist
- unrecognized function name:
- The mock for function %s is not defined.
- variable %s already exists in the same scope
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/d12467ddde2534c3.
Report an issue: GitHub.