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

  1. Verify the patch package's MD5/SHA-1 (Tinker patch digest) before applying; re-download if mismatched
  2. Use the same Tinker version in the gradle plugin and the on-device loader
  3. 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

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


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