{"record":{"id":"e5d8019249fd763e","repo":"xai-org/x-algorithm","slug":"variable-s-already-exists-in-the-same-scope","errorCode":null,"errorMessage":"variable %s already exists in the same scope","messagePattern":"variable (.+?) already exists in the same scope","errorType":"validation","errorClass":"SemanticCheckFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/compiler/CompilerScope.java","lineNumber":81,"sourceCode":"            ThriftType.EQUALITY_CHECK\n    );\n    checkAndMergeMap(\n            this.thriftStructTypes,\n            that.thriftStructTypes,\n            \"thrift struct type\",\n            ThriftStructType.EQUALITY_CHECK\n    );\n    checkAndMergeMap(\n            this.compilerUnits,\n            that.compilerUnits,\n            \"compiler unit\",\n            CompilerUnit.EQUALITY_CHECK\n    );\n  }\n\n  void defineVariable(Parameter parameter) throws SemanticCheckFailure {\n    if (variables.containsKey(parameter.getParameterName())) {\n      throw new SemanticCheckFailure(\n          String.format(\"variable %s already exists in the same scope\",\n              parameter.getParameterName()));\n    }\n    variables.put(parameter.getParameterName(), parameter);\n  }\n\n  boolean isVariableDefined(String variableText) {\n    return variables.containsKey(variableText);\n  }\n\n  Parameter getVariable(String variableText) {\n    return variables.get(variableText);\n  }\n\n  void defineType(ThriftType thriftType, String alias) {\n    thriftTypes.put(alias, thriftType);\n    for (CompilerUnit c : CompilerUnit.of(alias, thriftType)) {\n      compilerUnits.put(c.funcName(), c);","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/compiler/CompilerScope.java#L63-L99","documentation":"CompilerScope.defineVariable rejects binding a variable whose name already exists in the same scope, preventing shadowing-within-a-scope and ambiguous binder names.","triggerScenarios":"A lambda/binder construct (toAny, toFlatMap, toForEach, toFilter, toFoldl, toFoldl1) binding a variable name that is already defined in the current scope — e.g. nested 'forEach(x, ... forEach(x, ...))' in the same scope, or a binder colliding with a parameter.","commonSituations":"Nested comprehensions reusing the same binder name; renaming a binder to collide with an existing parameter; generated code that reuses binder names.","solutions":["Rename the inner binder to a unique name","Rename the colliding parameter or outer binder","In generated code, mangle binder names to guarantee uniqueness"],"exampleFix":"// before\nforEach(xs, forEach(xs, xs))\n// after\nforEach(xs, forEach(ys, ys))","handlingStrategy":"validation","validationCode":"if (scope.isVariableDefined(binderName)) throw new IllegalArgumentException(\"binder already defined: \" + binderName);","typeGuard":null,"tryCatchPattern":"catch (SemanticCheckFailure e) { /* rename the duplicate binder */ }","preventionTips":["Use unique binder names in nested comprehensions","Mangle generated binder names"],"tags":["botmaker","variable","shadowing","duplicate"],"backgroundTag":"duplicate-variable-declaration","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}