Tencent/tinker · error · IllegalArgumentException
patch file is null.
Error message
patch file is null.
What it means
IllegalArgumentException from DexPatchApplier.executeAndSaveTo: the patch file object is null. The applier requires a valid DexPatchFile (already parsed from a .dex patch stream) before it can apply operations and write the patched dex.
Source
Thrown at tinker-commons/src/main/java/com/tencent/tinker/commons/dexpatcher/DexPatchApplier.java:119
public DexPatchApplier(InputStream oldDexIn, InputStream patchFileIn) throws IOException {
this(new Dex(oldDexIn), new DexPatchFile(patchFileIn));
}
public DexPatchApplier(
Dex oldDexIn,
DexPatchFile patchFileIn
) {
this.oldDex = oldDexIn;
this.patchFile = patchFileIn;
this.patchedDex = new Dex(patchFileIn.getPatchedDexSize());
this.oldToPatchedIndexMap = new SparseIndexMap();
}
public void executeAndSaveTo(OutputStream out) throws IOException {
// Before executing, we should check if this patch can be applied to
// old dex we passed in.
if (this.patchFile == null) {
throw new IllegalArgumentException("patch file is null.");
}
if (this.patchFile.getVersion() > DexPatchFile.VERSION_02) {
final int oldDexAPI = this.oldDex.getTableOfContents().api;
final int expectedOldDexAPI = this.patchFile.getOldDexAPI();
if (oldDexAPI != expectedOldDexAPI) {
throw new IOException("old dex version mismatch! expetced: "
+ expectedOldDexAPI + ", actual: " + oldDexAPI);
}
}
byte[] oldDexSign = this.oldDex.computeSignature(false);
if (oldDexSign == null) {
throw new IOException("failed to compute old dex's signature.");
}
byte[] oldDexSignInPatchFile = this.patchFile.getOldDexSignature();
if (CompareUtils.uArrCompare(oldDexSign, oldDexSignInPatchFile) != 0) {
throw new IOException(
String.format(
"old dex signature mismatch! expected: %s, actual: %s",View on GitHub (pinned to 1b7ea02c23)
Solutions
- Parse and validate the DexPatchFile (it throws on bad magic/version in its constructor) before creating the applier
- Null-check the patch source and fail fast with a clear message upstream
- Ensure the patch entry extracted from the patch zip actually exists before decoding it
Example fix
// before
new DexPatchApplier(oldDex, null).executeAndSaveTo(out);
// after
if (patchFile == null) throw new IOException("no patch entry for this dex");
new DexPatchApplier(oldDex, patchFile).executeAndSaveTo(out); Defensive patterns
Strategy: validation
Validate before calling
if (patchFile == null) {
throw new IOException("missing dex patch entry; skip apply");
}
DexPatchApplier applier = new DexPatchApplier(oldDex, patchFile); Prevention
- Construct DexPatchFile eagerly so bad magic/version fail before the applier exists
- Never build the applier from a possibly-failed extraction result without a null check
When it happens
Trigger: Constructing DexPatchApplier(oldDex, null) or otherwise invoking executeAndSaveTo on an applier whose patchFile field is null (e.g., a failed patch-file parse left a null reference that was still passed on).
Common situations: Custom dex-patching pipelines that read the patch from a stream that failed earlier; logic that constructs the applier before validating the patch input.
Related errors
- Unexpected header: 0x${headerSize}
- Unexpected endian tag: 0x${endianTag}
- Map is unsorted at ${section}
- ${argument} too long: ${bytes.length}
- Bad CRC32: ${value}
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/0e6a52c0bc67da98.
Report an issue: GitHub.