Tencent/tinker · error · IllegalStateException
Unsupported abi:
Error message
Unsupported abi:
What it means
ShareTinkerInternals.getCurrentInstructionSet maps Build.CPU_ABI to an instruction set string (arm, arm64, x86, x86_64, mips, mips64). An ABI outside this list throws IllegalStateException("Unsupported abi: " + Build.CPU_ABI). The device reports an ABI the loader cannot translate into an odex ISA.
Source
Thrown at tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareTinkerInternals.java:147
currentInstructionSet = "arm";
break;
case "arm64-v8a":
currentInstructionSet = "arm64";
break;
case "x86":
currentInstructionSet = "x86";
break;
case "x86_64":
currentInstructionSet = "x86_64";
break;
case "mips":
currentInstructionSet = "mips";
break;
case "mips64":
currentInstructionSet = "mips64";
break;
default:
throw new IllegalStateException("Unsupported abi: " + Build.CPU_ABI);
}
}
ShareTinkerLog.d(TAG, "getCurrentInstructionSet:" + currentInstructionSet);
return currentInstructionSet;
}
public static boolean is32BitEnv() {
final String currISA = getCurrentInstructionSet();
return "arm".equals(currISA) || "x86".equals(currISA) || "mips".equals(currISA);
}
public static boolean isSystemOTA(String lastFingerPrint) {
String currentFingerprint = Build.FINGERPRINT;
if (lastFingerPrint == null
|| lastFingerPrint.equals("")
|| currentFingerprint == null
|| currentFingerprint.equals("")) {
ShareTinkerLog.d(TAG, "fingerprint empty:" + lastFingerPrint + ",current:" + currentFingerprint);View on GitHub (pinned to 1b7ea02c23)
Solutions
- Log Build.CPU_ABI (and CPU_ABI2/SUPPORTED_ABIS) on affected devices to identify the unknown value.
- Update Tinker to a version whose ABI map covers your devices (or patch the switch in a fork).
- Constrain patch distribution to supported ABI device sets.
- Catch IllegalStateException where instruction set feeds odex path computation and fall back to an ABI-derived mapping.
Example fix
// before
default:
throw new IllegalStateException("Unsupported abi: " + Build.CPU_ABI);
// after
default:
String[] abis = Build.SUPPORTED_ABIS;
String mapped = mapKnownAbi(abis != null && abis.length > 0 ? abis[0] : null);
if (mapped != null) currentInstructionSet = mapped;
else throw new IllegalStateException("Unsupported abi: " + Build.CPU_ABI); Defensive patterns
Strategy: type-guard
Validate before calling
String[] known = {"armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64"};
String abi = Build.CPU_ABI;
if (abi == null || !Arrays.asList(known).contains(abi)) {
// unsupported ABI: skip odex/instruction-set dependent paths
} Type guard
static boolean isSupportedAbi(String abi) {
if (abi == null) return false;
switch (abi) {
case "armeabi":
case "armeabi-v7a":
case "arm64-v8a":
case "x86":
case "x86_64":
case "mips":
case "mips64":
return true;
default:
return false;
}
} Try / catch
try {
String isa = ShareTinkerInternals.getCurrentInstructionSet();
} catch (IllegalStateException e) {
// 'Unsupported abi': device ABI unknown to this Tinker version
} Prevention
- Gate patch rollout by device ABI using your distribution backend.
- Log Build.SUPPORTED_ABIS from crash reports to detect new ABIs early.
- Upgrade Tinker when adopting new architectures (e.g. riscv64).
When it happens
Trigger: Calling getCurrentInstructionSet (directly or via optimizedPathFor on Android O+) on a device whose Build.CPU_ABI is not one of the six known values.
Common situations: Newer ABIs on preview/exotic hardware (e.g. riscv64), emulators reporting unusual ABI strings, or 32-bit processes on devices where CPU_ABI reflects the 64-bit primary ABI.
Related errors
- Bad isa num: {}
- getCurrentInstructionSet fail:
- patch %s extract failed (%s).
- Unable to find .rodata section.
- Bad isa num: {}
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/0ac07b367045aa25.
Report an issue: GitHub.