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

  1. Parse and validate the DexPatchFile (it throws on bad magic/version in its constructor) before creating the applier
  2. Null-check the patch source and fail fast with a clear message upstream
  3. 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

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


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/0e6a52c0bc67da98. Report an issue: GitHub.