{"record":{"id":"5dac38ac4e1ece0e","repo":"Tencent/tinker","slug":"patch-dex-opt-file-not-found-but-path-is-null-5dac38","errorCode":null,"errorMessage":"patch dex opt file not found, but path is null!!!!","messagePattern":"patch dex opt file not found, 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":231,"sourceCode":"                } else {\n                    ShareTinkerLog.e(TAG, \"patch dex file not found, but path is null!!!!\");\n                    throw new TinkerRuntimeException(\"patch dex file not found, but path is null!!!!\");\n                    // tinker.getLoadReporter().onLoadFileNotFound(null,\n                    //     ShareConstants.TYPE_DEX, false);\n                }\n                break;\n            case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_OPT_FILE_NOT_EXIST:\n                String dexOptPath = ShareIntentUtil.getStringExtra(intentResult,\n                    ShareIntentUtil.INTENT_PATCH_MISSING_DEX_PATH);\n                if (dexOptPath != null) {\n                    //we only pass one missing file\n                    ShareTinkerLog.e(TAG, \"patch dex opt file not found:%s\", dexOptPath);\n                    tinker.getLoadReporter().onLoadFileNotFound(new File(dexOptPath),\n                        ShareConstants.TYPE_DEX_OPT, false);\n\n                } else {\n                    ShareTinkerLog.e(TAG, \"patch dex opt file not found, but path is null!!!!\");\n                    throw new TinkerRuntimeException(\"patch dex opt file not found, but path is null!!!!\");\n                    // tinker.getLoadReporter().onLoadFileNotFound(null,\n                    //     ShareConstants.TYPE_DEX, false);\n                }\n                break;\n            case ShareConstants.ERROR_LOAD_PATCH_VERSION_LIB_DIRECTORY_NOT_EXIST:\n                if (patchVersionDirectory != null) {\n                    ShareTinkerLog.e(TAG, \"patch lib file directory not found:%s\", libraryDirectory.getAbsolutePath());\n                    tinker.getLoadReporter().onLoadFileNotFound(libraryDirectory,\n                        ShareConstants.TYPE_LIBRARY, true);\n                } else {\n                    //should be not here\n                    ShareTinkerLog.e(TAG, \"patch lib file directory not found, warning why the path is null!!!!\");\n                    throw new TinkerRuntimeException(\"patch lib file directory not found, warning why the path is null!!!!\");\n\n                    // tinker.getLoadReporter().onLoadFileNotFound(null,\n                    //     ShareConstants.TYPE_LIBRARY, true);\n                }\n","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java#L213-L249","documentation":"Defensive TinkerRuntimeException from the ERROR_LOAD_PATCH_VERSION_DEX_OPT_FILE_NOT_EXIST branch: the loader says an optimized-dex (odex/dex opt) artifact is missing, but INTENT_PATCH_MISSING_DEX_PATH was not supplied, so there is no path to report. It marks an inconsistency between the loader's error result and the data TinkerLoadResult can see.","triggerScenarios":"Result code ERROR_LOAD_PATCH_VERSION_DEX_OPT_FILE_NOT_EXIST arrives with a null INTENT_PATCH_MISSING_DEX_PATH extra. Realistic when the odex file was removed from the app's odex directory (e.g. by Android's dexopt cleanup or a full-dexopt re-run) while the versioned path extra got lost.","commonSituations":"Device storage pressure triggering ART to clear odex files; app moved to/from adopted storage; OS upgrade forcing re-dexopt; loader/library version mismatch dropping the extra.","solutions":["cleanPatch() then reinstall the patch so odex artifacts regenerate on next load.","Keep tinker components on one consistent version.","If it recurs after every OTA, treat onLoadFileNotFound(TYPE_DEX_OPT) in your LoadReporter as a signal to roll back the patch.","Preserve the tinker odex directory from cleanup tools."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (TinkerRuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"dex opt file not found\")) {\n        Tinker.with(app).cleanPatch();\n    } else throw e;\n}","preventionTips":["Treat odex loss after OS upgrades as a signal to roll back and re-apply the patch","Implement onLoadFileNotFound(TYPE_DEX_OPT) in your LoadReporter to react before a crash path"],"tags":["tinker","hotpatch","android","odex","missing-intent-extra"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}