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

  1. Ensure tinker is up to date — newer versions read the ISA via supported APIs or cached values compatible with hidden-API restrictions.
  2. 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.
  3. 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).
  4. 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

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


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/c55c3c53077bab2e. Report an issue: GitHub.