Tencent/tinker · error · TinkerRuntimeException

getPatchPathExtra, but intent is null

Error message

getPatchPathExtra, but intent is null

What it means

TinkerPatchService.getPatchPathExtra is a static convenience accessor that reads the patch file path extra from the intent that started the patch service. It throws immediately when handed a null Intent rather than returning null. Callers are usually app code (or a custom AbstractPatch) reacting to the patch service's intent.

Source

Thrown at tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/service/TinkerPatchService.java:92

        } catch (Throwable thr) {
            ShareTinkerLog.e(TAG, "run patch service fail, exception:" + thr);
        }
    }

    public static void setPatchProcessor(AbstractPatch upgradePatch, Class<? extends AbstractResultService> serviceClass) {
        upgradePatchProcessor = upgradePatch;
        resultServiceClass = serviceClass;
        //try to load
        try {
            Class.forName(serviceClass.getName());
        } catch (ClassNotFoundException e) {
            ShareTinkerLog.printErrStackTrace(TAG, e, "patch processor class not found.");
        }
    }

    public static String getPatchPathExtra(Intent intent) {
        if (intent == null) {
            throw new TinkerRuntimeException("getPatchPathExtra, but intent is null");
        }
        return ShareIntentUtil.getStringExtra(intent, PATCH_PATH_EXTRA);
    }

    public static boolean getPatchUseEmergencyMode(Intent intent) {
        if (intent == null) {
            throw new TinkerRuntimeException("getPatchUseEmergencyMode, but intent is null");
        }
        return ShareIntentUtil.getBooleanExtra(intent, PATCH_USE_EMERGENCY_MODE, false);
    }

    public static String getPatchResultExtra(Intent intent) {
        if (intent == null) {
            throw new TinkerRuntimeException("getPatchResultExtra, but intent is null");
        }
        return ShareIntentUtil.getStringExtra(intent, RESULT_CLASS_EXTRA);
    }

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Null-check the Intent before calling the helper.
  2. In service callbacks, guard the whole body when intent == null instead of passing it through.
  3. Use the standard TinkerInstaller.onReceiveUpgradePatch flow, which always supplies a populated intent.

Example fix

// before
String path = TinkerPatchService.getPatchPathExtra(intent);

// after
String path = intent != null ? TinkerPatchService.getPatchPathExtra(intent) : null;
if (path == null) return;
Defensive patterns

Strategy: validation

Validate before calling

if (intent == null) return; // service redelivered a null intent
String patchPath = TinkerPatchService.getPatchPathExtra(intent);
if (patchPath == null) return;

Prevention

When it happens

Trigger: Calling TinkerPatchService.getPatchPathExtra(intent) with a null Intent — e.g., in onHandleIntent of a restarted IntentService where the platform redelivers a null intent, or custom code that fetched the starting intent before it was set.

Common situations: Custom result/patch services that assume a non-null intent after process restart; defensive code paths receiving intent from getBindIntent-style helpers that can return null; porting tinker integration where the intent parameter is optional.

Related errors


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