iBotPeaches/Apktool · error · AndrolibException
Could not find file
Error message
Could not find file: {dexName} What it means
SmaliDecoder.decode(dexName, outDir) asked the ZipDexContainer for a specific dex entry and getEntry returned null, so no such dex file exists in the APK under that exact name. The message names the requested dex name.
Solutions
- List the real entry names and use one of them: `unzip -l app.apk | grep dex` or ZipDexContainer.getDexEntryNames()
- Check for case/path mismatches (Classes.dex vs classes.dex, leading directories)
- If decoding programmatically, derive dex names from the same container instance you decode from
- Confirm you opened the intended APK (base vs split), since dex names come from the opened file only
Example fix
// before
decoder.decode("Classes.dex", outDir); // wrong case -> Could not find file
// after
for (String name : new ZipFile(apk).stream()
.map(ZipEntry::getName)
.filter(n -> n.endsWith(".dex"))
.toList()) {
decoder.decode(name, outDir);
} Defensive patterns
Strategy: validation
Validate before calling
// Enumerate real dex names from the container itself before decoding
Collection<String> names;
try {
java.lang.reflect.Method unused = null; // placeholder
names = new ZipFile(apk).stream().map(ZipEntry::getName)
.filter(n -> n.endsWith(".dex")).toList();
} catch (IOException e) { throw new UncheckedIOException(e); }
if (!names.contains(dexName)) {
throw new IllegalArgumentException("No such dex entry '" + dexName + "' in " + apk + "; have: " + names);
} Try / catch
try {
decoder.decode(dexName, outDir);
} catch (AndrolibException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Could not find file")) {
// list container entries and correct the name; never blind-retry
} else { throw e; }
} Prevention
- Always derive dex names from the same container you decode from
- Treat dex names as case-sensitive on all platforms
- Prefer iterating all entries over hardcoding names like classes2.dex
When it happens
Trigger: Calling decode with a name that does not exactly match an entry in the container, e.g. "Classes.dex" vs "classes.dex", "classes2.dex" vs "classes2.dex" with a path prefix, or a name obtained from a different APK than the one opened.
Common situations: Hard-coded dex names in scripts after an app changed its multidex layout; case-sensitivity differences between platforms; iterating dex names from one split while decoding another split's file.
Related errors
- Cannot disassemble an odex file without deodexing it
- Could not open apk file
- Could not smali folder
- Could not baksmali file
- aapt2 binaries are not available for 32-bit platforms.
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/905a9e50efcd9956.
Report an issue: GitHub.
Appendix: source
Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/smali/SmaliDecoder.java:68
mDebugMode = debugMode;
mDexFiles = ConcurrentHashMap.newKeySet();
mInferredApiLevel = new AtomicInteger();
}
public Set<String> getDexFiles() {
return mDexFiles;
}
public int getInferredApiLevel() {
return mInferredApiLevel.get();
}
public void decode(String dexName, File outDir) throws AndrolibException {
try {
// Fetch the requested dex file from the dex container.
ZipDexContainer.DexEntry<DexBackedDexFile> dexEntry = mDexContainer.getEntry(dexName);
if (dexEntry == null) {
throw new AndrolibException("Could not find file: " + dexName);
}
// Add the requested dex file.
Map<Integer, DexBackedDexFile> dexFiles = new TreeMap<>();
dexFiles.put(1, dexEntry.getDexFile());
// Add additional dex files if it's a multi-dex container.
for (String dexEntryName : mDexContainer.getDexEntryNames()) {
if (dexEntryName.equals(dexName)) {
continue;
}
String prefix = dexName + "/";
if (!dexEntryName.startsWith(prefix)) {
continue;
}
int dexNum;View on GitHub (pinned to 79b63384d7)