iBotPeaches/Apktool · error · AndrolibException

Could not generate:

Error message

Could not generate: 

What it means

AndrolibException wrapping DirectoryException/IOException, thrown from ResDecoder's values-XML generation when serializing resource entries to res/values/*.xml fails. The first occurrence (line ~163) is the main values XML writer: it iterates a package's ResEntries and calls serializeToValuesXml on each; any I/O failure opening/writing the output stream, or a DirectoryException from the output Directory abstraction (missing parent dirs, file where dir expected), is rethrown with the target file name appended.

Solutions

  1. Check disk space and writability of the output directory (df -h ., touch test).
  2. Ensure no file occupies res/values paths and no other apktool process writes the same outDir.
  3. Retry with a clean output dir (`apktool d -f`) to rule out partial-state issues.

Example fix

# before
apktool d app.apk -o /readonly-mount/out
# after
apktool d -f app.apk -o ~/work/app-out
Defensive patterns

Strategy: try-catch

Validate before calling

if (!outDir.canWrite() || outDir.getUsableSpace() < 50L * 1024 * 1024) {
    throw new IllegalStateException("Output dir unwritable or low on space: " + outDir);
}

Try / catch

catch (AndrolibException e) { if (e.getCause() instanceof IOException io) { /* map to environment issue: space/perms, surface io.getMessage() */ } throw e; }

Prevention

When it happens

Trigger: decode() reaching values generation when the output tree is unwritable (permissions, disk full), an output path component was pre-occupied by a file, or an entry serializer hits an unexpected state producing a wrapped IOException.

Common situations: Out of disk during large app decode; outDir created on a read-only mount; antivirus locking generated XML files on Windows; concurrent decodes racing on the same output dir.

Related errors


AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14). Data as JSON: /api/errors/d350b36d70de0538. Report an issue: GitHub.

Appendix: source

Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResDecoder.java:163

            List<ResEntry> entries = mapEntry.getValue();
            entries.sort(Comparator.comparing(ResEntry::getResId));

            String outFileName = "res/values" + qualifiers + "/" + (typeName.endsWith("s") ? typeName
                : typeName.equals("^attr-private") ? "attrs-private" : typeName + "s") + ".xml";
            try (OutputStream out = outDir.getFileOutput(outFileName)) {
                serial.setOutput(out, null);
                serial.startDocument(null, null);
                serial.startTag(null, "resources");

                for (ResEntry entry : entries) {
                    // We already verified the value, cast directly.
                    ((ValuesXmlSerializable) entry.getValue()).serializeToValuesXml(serial, entry);
                }

                serial.endTag(null, "resources");
                serial.endDocument();
            } catch (DirectoryException | IOException ex) {
                throw new AndrolibException("Could not generate: " + outFileName, ex);
            }
        }
    }

    private void generatePublicXml(ResPackage pkg, Directory outDir, ResXmlSerializer serial)
            throws AndrolibException {
        List<ResEntrySpec> specs = Lists.newArrayList(pkg.listEntrySpecs());
        specs.sort(Comparator.comparing(ResEntrySpec::getResId));

        String outFileName = "res/values/public.xml";
        try (OutputStream out = outDir.getFileOutput(outFileName)) {
            serial.setOutput(out, null);
            serial.startDocument(null, null);
            serial.startTag(null, "resources");

            for (ResEntrySpec spec : specs) {
                serial.startTag(null, "public");
                serial.attribute(null, "type", spec.getTypeSpec().getName());

View on GitHub (pinned to 79b63384d7)