Tencent/tinker · error · TinkerRuntimeException
getCurrentInstructionSet fail:
Error message
getCurrentInstructionSet fail:
What it means
SharePatchFileUtil.optimizedPathFor computes the /oat/<isa>/xxx.odex path on Android O+. It calls ShareTinkerInternals.getCurrentInstructionSet(); if that throws (reflection into VMRuntime or unreadable Build.CPU_ABI), it is rethrown as TinkerRuntimeException('getCurrentInstructionSet fail:'). The odex location cannot be computed without knowing the ISA, so this is fatal to the dex-opt step.
Source
Thrown at tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/SharePatchFileUtil.java:478
/**
* change the jar file path as the makeDexElements do
* Android O change its path
*
* @param path
* @param optimizedDirectory
* @return
*/
public static String optimizedPathFor(File path, File optimizedDirectory) {
if (ShareTinkerInternals.isAfterAndroidO()) {
// dex_location = /foo/bar/baz.jar
// odex_location = /foo/bar/oat/<isa>/baz.odex
String currentInstructionSet;
try {
currentInstructionSet = ShareTinkerInternals.getCurrentInstructionSet();
} catch (Exception e) {
throw new TinkerRuntimeException("getCurrentInstructionSet fail:", e);
}
File parentFile = path.getParentFile();
String fileName = path.getName();
int index = fileName.lastIndexOf('.');
if (index > 0) {
fileName = fileName.substring(0, index);
}
String result = parentFile.getAbsolutePath() + "/oat/"
+ currentInstructionSet + "/" + fileName + ShareConstants.ODEX_SUFFIX;
return result;
}
String fileName = path.getName();
if (!fileName.endsWith(ShareConstants.DEX_SUFFIX)) {
int lastDot = fileName.lastIndexOf(".");
if (lastDot < 0) {View on GitHub (pinned to 1b7ea02c23)
Solutions
- Ensure tinker is up to date — newer versions read the ISA via supported APIs or cached values compatible with hidden-API restrictions.
- Check whether your app targets a SDK where Build.CPU_ABI is deprecated/empty (API 21+ multi-ABI) and rely on tinker's own detection instead of custom pre-checks.
- If you wrap this call yourself, catch TinkerRuntimeException and disable tinker's dex-opt path for that process (e.g. only load patch in the main process).
- Verify no proguard rules keep-away the android.os classes or tinker reflection helpers.
Example fix
// before
String odexPath = SharePatchFileUtil.optimizedPathFor(dexFile, optDir); // fatal if isa lookup fails
// after
String odexPath;
try {
odexPath = SharePatchFileUtil.optimizedPathFor(dexFile, optDir);
} catch (TinkerRuntimeException e) {
ShareTinkerLog.w(TAG, "isa lookup failed, skip custom odex path", e);
odexPath = new File(optDir, dexFile.getName() + ".odex").getAbsolutePath();
} Defensive patterns
Strategy: try-catch
Try / catch
try { path = SharePatchFileUtil.optimizedPathFor(dex, dir); } catch (TinkerRuntimeException e) { /* skip custom odex path, use default dir */ } Prevention
- Keep tinker (and its reflection targets) current for new Android hidden-API restrictions.
- Do not invoke optimizedPathFor in isolated/unusual processes where VMRuntime reflection may fail.
- Cache the instruction set once per process instead of repeated reflective lookups.
When it happens
Trigger: Any exception inside getCurrentInstructionSet(): reflection failure calling VMRuntime.is64BitRuntime (hidden-API blocking on newer Android), Build.CPU_ABI returning empty or an unrecognized value, or class-not-found on heavily restricted ROMs.
Common situations: Non-SDK interface restrictions (Android 9+ greylist) breaking the VMRuntime reflection; emulators or obscure ABIs; proguard/R8 stripping or renaming touching the reflection path; running in processes where the runtime is atypical (isolated processes).
Related errors
- Cannot query transaction code of performDexOptSecondary.
- createDelegate failed
- Unable to find .rodata section.
- Bad isa num: {}
- Field {} not found in {}
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/c55c3c53077bab2e.
Report an issue: GitHub.