{"record":{"id":"e403264714b4a116","repo":"Tencent/tinker","slug":"patch-s-extract-failed-s-e40326","errorCode":null,"errorMessage":"patch %s extract failed (%s).","messagePattern":"patch (.+?) extract failed \\((.+?)\\)\\.","errorType":"exception","errorClass":"TinkerRuntimeException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/SoDiffPatchInternal.java","lineNumber":210,"sourceCode":"                    } finally {\n                        IOHelper.closeQuietly(oldStream);\n                        IOHelper.closeQuietly(newStream);\n                    }\n\n                    //go go go bsdiff get the\n                    if (!SharePatchFileUtil.verifyFileMd5(extractedFile, fileMd5)) {\n                        ShareTinkerLog.w(TAG, \"Failed to recover diff file \" + extractedFile.getPath());\n                        manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);\n                        SharePatchFileUtil.safeDeleteFile(extractedFile);\n                        return false;\n                    }\n                    ShareTinkerLog.w(TAG, \"success recover bsdiff file: %s, use time: %d\",\n                        extractedFile.getPath(), (System.currentTimeMillis() - start));\n                }\n            }\n\n        } catch (Throwable e) {\n            throw new TinkerRuntimeException(\"patch \" + ShareTinkerInternals.getTypeString(type) + \" extract failed (\" + e.getMessage() + \").\", e);\n        } finally {\n            SharePatchFileUtil.closeZip(apk);\n            SharePatchFileUtil.closeZip(patch);\n        }\n        return true;\n    }\n\n}\n","sourceCodeStart":192,"sourceCodeEnd":219,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/SoDiffPatchInternal.java#L192-L219","documentation":"SoDiffPatchInternal's catch-all: any Throwable thrown while recovering native libraries from the patch (extracting old .so from the base APK, applying bsdiff or copying new/changed libraries, then MD5-verifying the result) is wrapped as 'patch lib extract failed'. Per-file MD5 verification failure is reported via onPatchTypeExtractFail and returns false; this exception indicates an unexpected Throwable escaped the so-recovery loop.","triggerScenarios":"Applying a so patch when: the old .so entry cannot be read from the base APK zip, the bsdiff stream for a library is malformed, output file creation under the patch lib directory fails (permissions/disk), or an abi-filtered APK lacks an expected library.","commonSituations":"Patch built for a different abi split or base APK than installed (split APKs with per-abi .so sets); devices with 16 KB page-size .so formats mismatching the patch's; disk full; patch generated with an incompatible tinker tool version.","solutions":["Generate the patch from the exact installed APK including the correct abi splits (use the same split/abi configuration when building the patch).","Verify patch file MD5 before applying.","Check free disk space and patch directory writability.","If targeting new page-size devices, regenerate patches with an updated tinker/bsdiff toolchain that matches the .so layout.","Inspect the wrapped cause via onPatchException."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Only distribute so patches for abis actually present in the installed APK\nSet<String> supportedAbis = Build.SUPPORTED_ABIS_SET or splits config;\nif (!serverPayload.patchAbis.containsAll(supportedAbisOfInstalledApk)) {\n    stripSoFromFlagsOrRefuse();\n}\nif (!SharePatchFileUtil.verifyFileMd5(new File(patchPath), serverPayload.patchMd5)) {\n    refuse(\"bad so patch\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    TinkerInstaller.onReceiveUpgradePatch(context, patchPath);\n} catch (TinkerRuntimeException e) {\n    reportPatchApplyFailure(e.getCause() != null ? e.getCause() : e);\n}","preventionTips":["Build so patches from the exact installed APK including matching abi splits.","Keep tinker gradle plugin and lib versions aligned; regenerate so patches after toolchain updates.","Check free disk space before applying, so recovery materializes full .so files on disk."],"tags":["tinker","android","native","so","bsdiff","abi"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}