{"record":{"id":"d87d7fb8d39056b5","repo":"Tencent/tinker","slug":"can-t-recognize-dex-mode","errorCode":null,"errorMessage":"can't recognize dex mode:{}","messagePattern":"can't recognize dex mode:(.+?)","errorType":"exception","errorClass":"TinkerRuntimeException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/ShareDexDiffPatchInfo.java","lineNumber":69,"sourceCode":"        this.path = path;\n        this.destMd5InDvm = destMd5InDvm;\n        this.destMd5InArt = destMd5InArt;\n        this.dexDiffMd5 = dexDiffMd5;\n        this.oldDexCrC = oldDexCrc;\n        this.newOrPatchedDexCrC = newOrPatchedDexCrC;\n        this.dexMode = dexMode;\n        if (dexMode.equals(ShareConstants.DEXMODE_JAR)) {\n            this.isJarMode = true;\n            if (SharePatchFileUtil.isRawDexFile(name)) {\n                realName = name + ShareConstants.JAR_SUFFIX;\n            } else {\n                realName = name;\n            }\n        } else if (dexMode.equals(ShareConstants.DEXMODE_RAW)) {\n            this.isJarMode = false;\n            this.realName = name;\n        } else {\n            throw new TinkerRuntimeException(\"can't recognize dex mode:\" + dexMode);\n        }\n    }\n\n    public static void parseDexDiffPatchInfo(String meta, ArrayList<ShareDexDiffPatchInfo> dexList) {\n        if (meta == null || meta.length() == 0) {\n            return;\n        }\n        String[] lines = meta.split(\"\\n\");\n        for (final String line : lines) {\n            if (line == null || line.length() <= 0) {\n                continue;\n            }\n            final String[] kv = line.split(\",\", 8);\n            if (kv == null || kv.length < 8) {\n                continue;\n            }\n\n            // key","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/ShareDexDiffPatchInfo.java#L51-L87","documentation":"ShareDexDiffPatchInfo's constructor validates the dexMode field from the patch's dex meta entry: it must be exactly ShareConstants.DEXMODE_JAR ('jar') or DEXMODE_RAW ('raw'). Anything else throws TinkerRuntimeException('can't recognize dex mode:'). The value comes from the meta.txt inside the patch package, which is generated by the tinker gradle plugin — so an unrecognized mode means a malformed/foreign meta file or a producer-consumer version skew.","triggerScenarios":"parseDexDiffPatchInfo() splits the dex meta line and constructs ShareDexDiffPatchInfo with a mode string that is neither 'jar' nor 'raw' — e.g. a hand-edited or truncated meta file, a meta produced by a newer/older plugin using a different mode token, or a patch package crafted by an incompatible tool.","commonSituations":"Building the patch with a much newer tinker gradle plugin than the loader in the base APK; tampered patch packages; splitting logic bugs where the meta columns shift (extra comma/path with newline producing a wrong field alignment).","solutions":["Regenerate the patch with the same tinker gradle plugin version as the runtime/loader in the base APK.","Reject and clean the bad patch: catch the exception during patch apply and call cleanPatch().","Verify meta-file integrity by validating the whole patch md5 before onReceiveUpgradePatch so tampered packages never reach parsing.","Do not hand-edit patch packages or meta files."],"exampleFix":"// before: passing any mode string\nnew ShareDexDiffPatchInfo(name, md5, crc, mode); // may throw\n\n// after: validate before constructing\nif (!ShareConstants.DEXMODE_JAR.equals(mode) && !ShareConstants.DEXMODE_RAW.equals(mode)) {\n    throw new IOException(\"bad dex mode in meta: \" + mode);\n}","handlingStrategy":"validation","validationCode":"static boolean isValidDexMode(String mode) {\n    return ShareConstants.DEXMODE_JAR.equals(mode) || ShareConstants.DEXMODE_RAW.equals(mode);\n}","typeGuard":null,"tryCatchPattern":"try {\n    ShareDexDiffPatchInfo.parseDexDiffPatchInfo(meta, dexList);\n} catch (TinkerRuntimeException e) {\n    // bad meta in patch package -> reject patch, do not install\n    reportInvalidPatch(e);\n}","preventionTips":["Generate patches only with the matching plugin version","Never hand-edit meta.txt or patch archives","Verify patch package md5 before apply"],"tags":["tinker","hotpatch","android","dex","meta-file","validation"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}