{"record":{"id":"64fe4bf4bd63a540","repo":"iBotPeaches/Apktool","slug":"could-not-smali-folder-smalidir-getname","errorCode":null,"errorMessage":"Could not smali folder: {smaliDir.getName()}","messagePattern":"Could not smali folder: (.+?)","errorType":"exception","errorClass":"AndrolibException","httpStatus":null,"severity":"error","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/smali/SmaliBuilder.java","lineNumber":96,"sourceCode":"                    if (cause != null) {\n                        ex.initCause(cause);\n                    }\n                    throw ex;\n                }\n            }\n\n            if (dexFile.exists()) {\n                OS.rmfile(dexFile);\n            } else {\n                File parentDir = dexFile.getParentFile();\n                if (parentDir != null) {\n                    OS.mkdir(parentDir);\n                }\n            }\n\n            dexBuilder.writeTo(new FileDataStore(dexFile));\n        } catch (DirectoryException | IOException | RuntimeException ex) {\n            throw new AndrolibException(\"Could not smali folder: \" + smaliDir.getName(), ex);\n        }\n    }\n\n    private boolean buildFile(File smaliFile, DexBuilder dexBuilder) throws IOException, RecognitionException {\n        try (InputStreamReader reader = new InputStreamReader(\n                Files.newInputStream(smaliFile.toPath()), StandardCharsets.UTF_8)) {\n            smaliFlexLexer lexer = new smaliFlexLexer(reader, mApiLevel);\n            lexer.setSourceFile(smaliFile);\n\n            CommonTokenStream tokens = new CommonTokenStream(lexer);\n\n            if (PRINT_TOKENS) {\n                for (Token token : tokens.getTokens()) {\n                    if (token.getChannel() != smaliParser.HIDDEN) {\n                        System.out.println(smaliParser.tokenNames[token.getType()] + \": \" + token.getText());\n                    }\n                }\n            }","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/smali/SmaliBuilder.java#L78-L114","documentation":"SmaliBuilder.build failed while assembling smali sources back into a classes.dex: the smali/dexlib writer threw an IOException, DirectoryException, or RuntimeException (e.g. assembly error from invalid smali). The message names the smali folder being built and keeps the cause.","triggerScenarios":"Calling ApkDecoder.build() / SmaliBuilder on a decoded project where smali files contain syntax or semantic errors, where the output dex path is not writable, or where a parent directory cannot be created. The catch also covers RuntimeExceptions from the dex writer on malformed input.","commonSituations":"Rebuilding after hand-editing smali and introducing register/label errors; rebuilding on a read-only or full disk; smali edited with an api-level mismatch causing writer failures; leftover classes.dex that cannot be replaced.","solutions":["Read the attached cause — for smali syntax errors it pinpoints file and line; fix the reported smali file","If you edited smali, validate registers/labels (smali/baksmali tooling or an IDE plugin) before rebuilding","Check the output directory is writable and has free space; ensure no stale locked classes.dex blocks the write","Retry the decode→build cycle without manual edits to confirm the original smali assembles; if it does not, update apktool (bundled smali version may be too old for the dex)"],"exampleFix":"# before\n# edited smali_classes2/com/example/MainActivity.smali and broke a register count\napktool b app\n# -> Could not smali folder: smali_classes2\n\n# after\n# fix the reported line (cause exception names file:line), e.g. restore .registers\napktool b app","handlingStrategy":"try-catch","validationCode":"// Smoke-assemble smali before a full build is not cheap; instead keep edits minimal and\n// verify the decoded project builds BEFORE editing:\n//   apktool d app.apk -o orig && apktool b orig   // baseline must pass\n// Then diff your edits against orig when a build fails.","typeGuard":null,"tryCatchPattern":"try {\n    new SmaliBuilder(apkInfo, outDir, apiLevel).build();\n} catch (AndrolibException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not smali folder\")) {\n        Throwable cause = e.getCause();\n        // cause is often a smali compile error naming file:line — surface it directly\n        log.error(\"Smali assembly failed in {}: {}\", e.getMessage(), cause);\n    } else { throw e; }\n}","preventionTips":["Baseline-build the unmodified decode before editing smali","Make small smali edits and rebuild after each change","Keep disk space and write permissions on the output tree healthy"],"tags":["apktool","smali","build","dex"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}