{"record":{"id":"b241ddea20d33a37","repo":"skylot/jadx","slug":"unknown-variable-in-template","errorCode":null,"errorMessage":"Unknown variable: '{}' in template: {}","messagePattern":"Unknown variable: '(.+?)' in template: (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/export/TemplateFile.java","lineNumber":159,"sourceCode":"\n\t\t\t\t\tcase START:\n\t\t\t\t\t\tparser.state = State.NONE;\n\t\t\t\t\t\treturn \"{\" + ch;\n\n\t\t\t\t\tcase END:\n\t\t\t\t\t\tthrow new JadxRuntimeException(\"Expected variable end: '\" + parser.curVariable\n\t\t\t\t\t\t\t\t+ \"' (missing second '}')\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tparser.skip = false;\n\t\treturn null;\n\t}\n\n\tprivate String processVar(String varName, boolean rawValue) {\n\t\tString str = values.get(varName);\n\t\tif (str == null) {\n\t\t\tthrow new JadxRuntimeException(\"Unknown variable: '\" + varName\n\t\t\t\t\t+ \"' in template: \" + templateName);\n\t\t}\n\t\tif (!rawValue) {\n\t\t\tFunction<String, String> sanitizer = valueSanitizer;\n\t\t\tif (sanitizer != null) {\n\t\t\t\treturn sanitizer.apply(str);\n\t\t\t}\n\t\t}\n\t\treturn str;\n\t}\n}\n","sourceCodeStart":141,"sourceCodeEnd":171,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/export/TemplateFile.java#L141-L171","documentation":"Thrown as JadxRuntimeException by TemplateFile.processVar() when values.get(varName) returns null, meaning the template references a variable that was never registered via TemplateFile.add(name, value). The template engine requires every '{{variable}}' placeholder to have a corresponding add() call before build()/save(). The error includes both the variable name and the template file name.","triggerScenarios":"A template file contains '{{projectName}}' but the calling code never calls tmpl.add(\"projectName\", value). This occurs when a template is updated to reference a new variable but the generator code is not updated to supply it, or when a variable name has a typo mismatch between template and code.","commonSituations":"Internal jadx bug where a template and its generator code are out of sync. Custom export templates referencing variables the generator does not provide. Case-sensitivity or whitespace issues in variable names (note: variable names are collected character-by-character, so embedded whitespace matters).","solutions":["Check the template file (named in the error message) for all '{{...}}' placeholders and ensure each has a matching tmpl.add() call.","Verify variable name spelling and case match exactly between template and code.","If using stock jadx templates, report the bug with the template name and variable name from the error.","For custom templates, add a tmpl.add(varName, value) for every referenced variable, or remove unused placeholders from the template."],"exampleFix":"// before — template has {{version}} but code does not add it\nTemplateFile tmpl = TemplateFile.fromResources(\"/export/build.tmpl\");\ntmpl.add(\"projectName\", name);\ntmpl.save(file); // error: Unknown variable 'version'\n\n// after — add all referenced variables\nTemplateFile tmpl = TemplateFile.fromResources(\"/export/build.tmpl\");\ntmpl.add(\"projectName\", name);\ntmpl.add(\"version\", version);\ntmpl.save(file);","handlingStrategy":"validation","validationCode":"// Before rendering, collect all variable names from the template\n// and ensure each is registered via add()\nSet<String> requiredVars = extractTemplateVariables(templateContent);\nfor (String var : requiredVars) {\n    if (!values.containsKey(var)) {\n        throw new IllegalStateException(\"Missing template variable: \" + var);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    tmpl.save(outFile);\n} catch (JadxRuntimeException e) {\n    if (e.getMessage().contains(\"Unknown variable\")) {\n        LOG.error(\"Template variable not provided: {}\", e.getMessage());\n        // Add the missing variable or fix the template\n    } else {\n        throw e;\n    }\n}","preventionTips":["Call tmpl.add(varName, value) for every '{{varName}}' placeholder in the template.","Match variable names exactly (case-sensitive, no trailing whitespace).","When updating templates, update the generator code that supplies variables in lockstep.","Add a test that renders each template with all expected variables to catch mismatches early."],"tags":["jadx","template","missing-variable","configuration","template-engine"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}