{"record":{"id":"ec780b98209507f3","repo":"Tencent/tinker","slug":"patch-dex-file-md5-is-mismatch-but-path-is-null-ec780b","errorCode":null,"errorMessage":"patch dex file md5 is mismatch, but path is null!!!!","messagePattern":"patch dex file md5 is mismatch, but path is null!!!!","errorType":"exception","errorClass":"TinkerRuntimeException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java","lineNumber":274,"sourceCode":"                    ShareTinkerLog.e(TAG, \"patch lib file not found:%s\", libPath);\n                    tinker.getLoadReporter().onLoadFileNotFound(new File(libPath),\n                        ShareConstants.TYPE_LIBRARY, false);\n                } else {\n                    ShareTinkerLog.e(TAG, \"patch lib file not found, but path is null!!!!\");\n                    throw new TinkerRuntimeException(\"patch lib file not found, but path is null!!!!\");\n                    // tinker.getLoadReporter().onLoadFileNotFound(null,\n                    //     ShareConstants.TYPE_LIBRARY, false);\n                }\n                break;\n            case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_CLASSLOADER_NULL:\n                ShareTinkerLog.e(TAG, \"patch dex load fail, classloader is null\");\n                break;\n            case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_MD5_MISMATCH:\n                String mismatchPath = ShareIntentUtil.getStringExtra(intentResult,\n                    ShareIntentUtil.INTENT_PATCH_MISMATCH_DEX_PATH);\n                if (mismatchPath == null) {\n                    ShareTinkerLog.e(TAG, \"patch dex file md5 is mismatch, but path is null!!!!\");\n                    throw new TinkerRuntimeException(\"patch dex file md5 is mismatch, but path is null!!!!\");\n                } else {\n                    ShareTinkerLog.e(TAG, \"patch dex file md5 is mismatch: %s\", mismatchPath);\n                    tinker.getLoadReporter().onLoadFileMd5Mismatch(new File(mismatchPath),\n                        ShareConstants.TYPE_DEX);\n                }\n                break;\n            case ShareConstants.ERROR_LOAD_PATCH_REWRITE_PATCH_INFO_FAIL:\n                ShareTinkerLog.i(TAG, \"rewrite patch info file corrupted\");\n                tinker.getLoadReporter().onLoadPatchInfoCorrupted(oldVersion, newVersion, patchInfoFile);\n                break;\n            case ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_DIRECTORY_NOT_EXIST:\n                if (patchVersionDirectory != null) {\n                    ShareTinkerLog.e(TAG, \"patch resource file directory not found:%s\", resourceDirectory.getAbsolutePath());\n                    tinker.getLoadReporter().onLoadFileNotFound(resourceDirectory,\n                        ShareConstants.TYPE_RESOURCE, true);\n                } else {\n                    //should be not here\n                    ShareTinkerLog.e(TAG, \"patch resource file directory not found, warning why the path is null!!!!\");","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java#L256-L292","documentation":"In the ERROR_LOAD_PATCH_VERSION_DEX_MD5_MISMATCH branch, TinkerLoadResult expects INTENT_PATCH_MISMATCH_DEX_PATH naming the dex whose MD5 no longer matches the patch metadata. A null path makes it impossible to report via onLoadFileMd5Mismatch, so Tinker throws. The underlying trigger is dex content on disk differing from the recorded checksum — the null-path throw is the secondary inconsistency.","triggerScenarios":"Loader detects a dex file whose MD5 differs from the value in the patch's dex metadata and returns ERROR_LOAD_PATCH_VERSION_DEX_MD5_MISMATCH, but fails to attach INTENT_PATCH_MISMATCH_DEX_PATH.","commonSituations":"Disk corruption or truncation of a patch dex; anti-tampering software modifying dex files; hotpatch attempt after a partially-applied patch; version mismatch between components.","solutions":["cleanPatch() to remove the tampered/corrupt patch and restore base behavior, then re-apply a freshly downloaded patch.","Verify the downloaded patch file's md5 on the server side before handing it to TinkerInstaller.onReceiveUpgradePatch.","Check device storage health if it recurs on the same devices.","Align tinker component versions."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before handing a downloaded patch to tinker, verify whole-file md5\npublic static boolean verifyFileMd5(File patch, String expected) throws IOException {\n    return expected != null && expected.equals(SharePatchFileUtil.getMD5(patch));\n}","typeGuard":null,"tryCatchPattern":"catch (TinkerRuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"md5 is mismatch\")) {\n        Tinker.with(app).cleanPatch();\n    } else throw e;\n}","preventionTips":["Verify patch md5 server-side and client-side before apply","Do not modify patch files after download"],"tags":["tinker","hotpatch","android","md5","integrity"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}