iBotPeaches/Apktool · warning · AndrolibException
Undefined decoder for type: %s
Error message
Undefined decoder for type: %s
What it means
Thrown by ResFileDecoder's private decode(type, ...) when no ResStreamDecoder is registered in the decoder map for the requested Type (UNKNOWN, BINARY_XML, or PNG_9PATCH). It indicates the ResFileDecoder was constructed with an incomplete decoder map. The public decode(ResEntry, ...) entry point catches AndrolibException and replaces the value with ResPrimitive.NULL plus a warning, so direct impact is limited to callers of that public path or to a NULL resource appearing in output.
Source
Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java:111
// Assume the file is a raw PNG.
// Some apps contain unprocessed dummy 3x3 9-patch PNGs.
// Extract them as-is, let aapt2 process them properly later.
Log.d(TAG, "Could not find 9-patch chunk in file: " + inFileName);
}
}
decode(Type.UNKNOWN, inDir, inFileName, outDir, outFileName);
} catch (AndrolibException ignored) {
Log.w(TAG, "Could not decode file, replacing by NULL value: " + inFileName);
entry.setValue(ResPrimitive.NULL);
}
}
private void decode(Type type, Directory inDir, String inFileName, Directory outDir, String outFileName)
throws AndrolibException {
ResStreamDecoder decoder = mDecoders.get(type);
if (decoder == null) {
throw new AndrolibException("Undefined decoder for type: " + type);
}
boolean success = false;
try (
InputStream in = inDir.getFileInput(inFileName);
OutputStream out = outDir.getFileOutput(outFileName)
) {
decoder.decode(in, out);
success = true;
} catch (DirectoryException | IOException ex) {
throw new AndrolibException(ex);
} finally {
if (!success) {
outDir.removeFile(outFileName);
}
}
}
}View on GitHub (pinned to 79b63384d7)
Solutions
- Register a decoder for every ResFileDecoder.Type value, especially Type.UNKNOWN (typically ResRawStreamDecoder) since it is the fallback path.
- Prefer using apktool's own wiring (ApkDecoder) rather than constructing ResFileDecoder manually.
- After upgrade, re-check the Type enum and add mappings for any new values.
Example fix
// before Map<ResFileDecoder.Type, ResStreamDecoder> decoders = new EnumMap<>(ResFileDecoder.Type.class); decoders.put(ResFileDecoder.Type.BINARY_XML, xmlDecoder); new ResFileDecoder(decoders); // UNKNOWN missing -> "Undefined decoder for type: UNKNOWN" // after Map<ResFileDecoder.Type, ResStreamDecoder> decoders = new EnumMap<>(ResFileDecoder.Type.class); decoders.put(ResFileDecoder.Type.BINARY_XML, xmlDecoder); decoders.put(ResFileDecoder.Type.PNG_9PATCH, ninePatchDecoder); decoders.put(ResFileDecoder.Type.UNKNOWN, new ResRawStreamDecoder()); new ResFileDecoder(decoders);
Defensive patterns
Strategy: validation
Validate before calling
// Register every Type before constructing ResFileDecoder
Map<ResFileDecoder.Type, ResStreamDecoder> decoders = new EnumMap<>(ResFileDecoder.Type.class);
for (ResFileDecoder.Type t : ResFileDecoder.Type.values()) {
if (!decoders.containsKey(t)) throw new IllegalStateException("Missing decoder for " + t);
} Try / catch
try {
resFileDecoder.decode(entry, inDir, outDir, resFileMap);
} catch (AndrolibException ex) {
// public path already downgrades to ResPrimitive.NULL; this only fires for misuse
Log.w(TAG, "decode failed: " + ex.getMessage(), ex);
} Prevention
- Always map Type.UNKNOWN (raw copy fallback) in the decoder map
- Prefer apktool's built-in ApkDecoder wiring over hand-built maps
- After upgrading apktool-lib, re-check the Type enum for new values
When it happens
Trigger: Building ResFileDecoder with a map missing Type.UNKNOWN, Type.BINARY_XML (AXmlResourceParser), or Type.PNG_9PATCH; third-party code reusing ResFileDecoder with a custom partial map; refactoring that drops a decoder registration.
Common situations: Embedding apktool-lib and hand-assembling the decoder map instead of using the framework's default wiring; version upgrades where the Type enum gained values not present in an old map; test harnesses with stub decoders.
Related errors
- Could not open apk file: {apkFile}
- Legacy aapt is no longer supported.
- Stream advanced past chunk end.
- Unexpected EOF while skipping chunk.
- Error while skipping chunk.
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/c75cfca330f8836d.
Report an issue: GitHub.