Tencent/tinker · error · TinkerRuntimeException
you must install tinker before get tinker sInstance
Error message
you must install tinker before get tinker sInstance
What it means
Tinker.with(Context) is the accessor for the Tinker singleton, but it refuses to run before TinkerInstaller.install(...) (which sets sInstalled = true), throwing TinkerRuntimeException("you must install tinker before get tinker sInstance"). This enforces the library's initialization contract: install defines the reporters, listener and flags before anything can obtain the instance. In the no-op artifact the same guard exists so misordered code fails identically in no-op builds.
Source
Thrown at tinker-android/tinker-android-lib-no-op/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java:101
this.tinkerFlags = tinkerFlags;
this.patchDirectory = patchDirectory;
this.patchInfoFile = patchInfoFile;
this.patchInfoLockFile = patchInfoLockFile;
this.isMainProcess = isInMainProc;
this.tinkerLoadVerifyFlag = tinkerLoadVerifyFlag;
this.isPatchProcess = isPatchProcess;
}
/**
* init with default config tinker
* for safer, you must use @{link TinkerInstaller.install} first!
*
* @param context we will use the application context
* @return the Tinker object
*/
public static Tinker with(Context context) {
if (!sInstalled) {
throw new TinkerRuntimeException("you must install tinker before get tinker sInstance");
}
synchronized (Tinker.class) {
if (sInstance == null) {
sInstance = new Builder(context).build();
}
}
return sInstance;
}
/**
* create custom tinker by {@link Tinker.Builder}
* please do it when very first your app start.
*
* @param tinker
*/
public static void create(Tinker tinker) {
if (sInstance != null) {
throw new TinkerRuntimeException("Tinker instance is already set.");View on GitHub (pinned to 1b7ea02c23)
Solutions
- Call TinkerInstaller.install(defaultApplicationLike, ...) at the very start of Application.onCreate (or attachBaseContext) before any Tinker.with() consumer runs.
- Guard every accessor with Tinker.isTinkerInstalled() (the API exists on this class) and degrade gracefully when not installed.
- Verify install runs in ALL processes that touch Tinker — check your process-splitting logic in Application.
Example fix
// before
public void onCreate() {
super.onCreate();
Tinker.with(this).getTinkerLoadResultIfWithPatch(); // throws
TinkerInstaller.install(appLike, ...);
}
// after
public void onCreate() {
super.onCreate();
TinkerInstaller.install(appLike, loadReport, patchReport, patchListener, ...);
if (Tinker.isTinkerInstalled()) {
Tinker.with(this).getTinkerLoadResultIfWithPatch();
}
} Defensive patterns
Strategy: validation
Validate before calling
if (Tinker.isTinkerInstalled()) {
Tinker tinker = Tinker.with(context);
// use tinker...
} else {
Log.w(TAG, "Tinker not installed; skipping Tinker.with()");
} Try / catch
try {
Tinker tinker = Tinker.with(context);
} catch (TinkerRuntimeException e) {
// install was never called in this process
Log.w(TAG, "Tinker.with before install", e);
} Prevention
- Call TinkerInstaller.install at the top of Application.onCreate in every process
- Wrap all Tinker accessors with isTinkerInstalled() checks
- Watch for secondary processes that skip your init path
When it happens
Trigger: Calling Tinker.with(context) (directly or via helpers like TinkerLoadLibrary/upgrade processors that internally fetch the instance) before TinkerInstaller.install(context, ...) has run in this process.
Common situations: App code that queries Tinker.with() in Application.attachBaseContext while install happens later in onCreate; a secondary process (patch service, push process) whose Application path skips the install call; unit tests or no-op build variants where install was omitted but downstream calls remain.
Related errors
- Tinker instance is already set.
- Tinker instance is already set.
- libName or context is null!
- libName or appLike is null!
- upgradePatchProcessor is null.
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/d401d63f5d5ea20b.
Report an issue: GitHub.