{"record":{"id":"67b4bdd7d9d1869c","repo":"skylot/jadx","slug":"template-already-processed","errorCode":null,"errorMessage":"Template already processed","messagePattern":"Template already processed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/export/TemplateFile.java","lineNumber":79,"sourceCode":"\t\ttry (ByteArrayOutputStream out = new ByteArrayOutputStream()) {\n\t\t\tprocess(out);\n\t\t\treturn out.toString();\n\t\t}\n\t}\n\n\tpublic void save(File outFile) throws IOException {\n\t\ttry (OutputStream out = new FileOutputStream(outFile)) {\n\t\t\tprocess(out);\n\t\t}\n\t}\n\n\tpublic void setValueSanitizer(@Nullable Function<String, String> valueSanitizer) {\n\t\tthis.valueSanitizer = valueSanitizer;\n\t}\n\n\tprivate void process(OutputStream out) throws IOException {\n\t\tif (template.available() == 0) {\n\t\t\tthrow new IOException(\"Template already processed\");\n\t\t}\n\t\ttry (InputStream in = new BufferedInputStream(template)) {\n\t\t\tParserState state = new ParserState();\n\t\t\twhile (true) {\n\t\t\t\tint ch = in.read();\n\t\t\t\tif (ch == -1) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tString str = process(state, (char) ch);\n\t\t\t\tif (str != null) {\n\t\t\t\t\tout.write(str.getBytes());\n\t\t\t\t} else if (!state.skip) {\n\t\t\t\t\tout.write(ch);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/export/TemplateFile.java#L61-L97","documentation":"Thrown as IOException by TemplateFile.process() when template.available() == 0, indicating the underlying InputStream has already been fully consumed. TemplateFile wraps a single InputStream and is designed for single-use: calling build() or save() consumes the stream. A second call finds no bytes available and throws.","triggerScenarios":"TemplateFile.build() or TemplateFile.save() is called more than once on the same TemplateFile instance. The first call drains the InputStream; the second call sees available() == 0 and throws.","commonSituations":"Internal jadx code that caches a TemplateFile and attempts to render it twice (e.g. once for preview, once for save). Custom code reusing a TemplateFile instance. Not user-facing in normal decompilation — typically a programming error in export or template-consuming code.","solutions":["Create a new TemplateFile instance (via fromResources or a fresh InputStream) for each render call.","If you need the output multiple times, call build() once and reuse the resulting String.","If developing jadx export code, load the template fresh for each file write."],"exampleFix":"// before — reusing a single TemplateFile\nTemplateFile tmpl = TemplateFile.fromResources(\"/export/x.tmpl\");\ntmpl.add(\"name\", value);\ntmpl.save(file1);\ntmpl.save(file2); // IOException: already processed\n\n// after — create fresh instances\nTemplateFile tmpl1 = TemplateFile.fromResources(\"/export/x.tmpl\");\ntmpl1.add(\"name\", value);\ntmpl1.save(file1);\n\nTemplateFile tmpl2 = TemplateFile.fromResources(\"/export/x.tmpl\");\ntmpl2.add(\"name\", value);\ntmpl2.save(file2);","handlingStrategy":"validation","validationCode":"// TemplateFile is single-use; create a fresh instance for each render\n// Do NOT reuse the same TemplateFile instance\nTemplateFile tmpl1 = TemplateFile.fromResources(path);\ntmpl1.add(\"key\", value);\nString result = tmpl1.build(); // consumes the stream\n\n// For a second render, create a new instance\nTemplateFile tmpl2 = TemplateFile.fromResources(path);\ntmpl2.add(\"key\", value);\ntmpl2.save(outputFile);","typeGuard":null,"tryCatchPattern":"try {\n    tmpl.save(outFile);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"already processed\")) {\n        // Recreate the template and retry\n        tmpl = TemplateFile.fromResources(originalPath);\n        tmpl.add(\"key\", value);\n        tmpl.save(outFile);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Never call build() or save() twice on the same TemplateFile instance.","If you need output in memory and on disk, call build() once and write the String to disk separately.","Create a fresh TemplateFile for each file write in export code."],"tags":["jadx","template","io","single-use","stream-consumed"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}