Tencent/tinker · critical · IllegalStateException
bad patch operation sequence. addCounter: %d, addCount: %d,
Error message
bad patch operation sequence. addCounter: %d, addCount: %d, delCounter: %d, delCount: %d, replaceCounter: %d, replaceCount:%d
What it means
IllegalStateException from DexSectionPatchAlgorithm's patch-application loop: after walking old and patched item lists, the executed number of add/delete/replace operations does not match the counts recorded in the patch file header. The operation stream and the item cursors desynchronized, indicating a corrupt or incompatible patch file.
Source
Thrown at tinker-commons/src/main/java/com/tencent/tinker/commons/dexpatcher/algorithms/patch/DexSectionPatchAlgorithm.java:229
int patchedOffset = writePatchedItem(oldItem);
updateIndexOrOffset(
this.oldToPatchedIndexMap,
oldIndex,
getItemOffsetOrIndex(oldIndex, oldItem),
patchedIndex,
patchedOffset
);
++oldIndex;
++patchedIndex;
}
}
if (addActionCursor != addedItemCount || deletedItemCounter != deletedItemCount
|| replaceActionCursor != replacedItemCount
) {
throw new IllegalStateException(
String.format(
"bad patch operation sequence. addCounter: %d, addCount: %d, "
+ "delCounter: %d, delCount: %d, "
+ "replaceCounter: %d, replaceCount:%d",
addActionCursor,
addedItemCount,
deletedItemCounter,
deletedItemCount,
replaceActionCursor,
replacedItemCount
)
);
}
onPatchAlgorithmEnd();
}
}
View on GitHub (pinned to 1b7ea02c23)
Solutions
- Verify the patch package's MD5/SHA-1 (Tinker patch digest) before applying; re-download if mismatched
- Use the same Tinker version in the gradle plugin and the on-device loader
- Regenerate the patch with the current toolchain
Defensive patterns
Strategy: validation
Validate before calling
// Verify whole patch package digest before applying any dex patch
if (!Arrays.equals(expectedMd5, SharePatchFileUtil.getMD5(patchFile))) {
throw new IOException("patch digest mismatch; redownload");
} Try / catch
try {
applier.executeAndSaveTo(out);
} catch (IllegalStateException e) {
if (String.valueOf(e.getMessage()).startsWith("bad patch operation sequence")) {
// corrupt or incompatible patch: redownload / regenerate, never retry as-is
} else { throw e; }
} Prevention
- Always verify patch MD5/SHA before application (Tinker does this at package level; keep it enabled)
- Pin identical Tinker plugin and runtime versions across your release pipeline
When it happens
Trigger: Applying a dex section patch where the add/del/replace counters in DexSectionPatchAlgorithm's run loop end up unequal to addedItemCount/deletedItemCount/replacedItemCount from the patch — e.g., truncated patch data or generator/applier version mismatch.
Common situations: Patch file corrupted in transit or by partial download; generating patches with one Tinker version and applying with another (different algorithm versions); tampered patch zips.
Related errors
- old dex version mismatch! expetced:
- failed to compute old dex's signature.
- old dex signature mismatch! expected: %s, actual: %s
- bad dex patch file magic:
- patch file is null.
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/dd38bc3412a1613a.
Report an issue: GitHub.