{"record":{"id":"8aa25708417b10be","repo":"skylot/jadx","slug":"expected-variable-end-missing-second","errorCode":null,"errorMessage":"Expected variable end: '{}' (missing second '}')","messagePattern":"Expected variable end: '(.+?)' \\(missing second '\\}'\\)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/export/TemplateFile.java","lineNumber":147,"sourceCode":"\t\t\t\t\t\t\tvarName = varName.substring(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn processVar(varName, rawValue);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tswitch (state) {\n\t\t\t\t\tcase VARIABLE:\n\t\t\t\t\t\tparser.curVariable.append(ch);\n\t\t\t\t\t\tparser.skip = true;\n\t\t\t\t\t\treturn null;\n\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);","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/export/TemplateFile.java#L129-L165","documentation":"Thrown as JadxRuntimeException by TemplateFile's character processor when the parser is in the END state (one closing '}' seen after a variable) and encounters a character that is not '}'. The template syntax requires variables to be enclosed in double braces '{{variable}}'; a single '}' after a variable name leaves the parser in an intermediate END state expecting a second '}'. Any non-'}' character in that state is malformed.","triggerScenarios":"A template file contains '{{variable}x' (only one closing brace) or '{{variable}' followed by text. The parser transitions: NONE -> START (first '{') -> VARIABLE (second '{', collects chars) -> END (first '}') -> expects second '}'. If the next char is not '}', this throws.","commonSituations":"Malformed template files bundled with jadx (should not happen in releases). Custom templates with incorrect brace syntax. Template corruption during build or packaging. Not typically user-facing unless custom templates are used.","solutions":["Inspect the template file named in the error (templateName is included in related context) and fix the brace syntax: ensure every '{{' has a matching '}}'.","If using stock jadx templates, report the bug — bundled templates should be well-formed.","Validate custom templates with a simple grep for unbalanced '{{' / '}}' before use."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate template brace balance before processing\nString content = new String(getClass().getResourceAsStream(path).readAllBytes());\nlong openCount = content.chars().filter(c -> c == '{').count();\nlong closeCount = content.chars().filter(c -> c == '}').count();\nif (openCount != closeCount || openCount % 2 != 0) {\n    throw new IllegalStateException(\"Template has unbalanced braces: \" + path);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure template files use matching '{{' and '}}' pairs for all variables.","Validate custom templates for brace balance before use.","Report malformed bundled templates as jadx bugs."],"tags":["jadx","template","syntax-error","parser","malformed-braces"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}