Tencent/tinker · error · TinkerRuntimeException
Context must not be null.
Error message
Context must not be null.
What it means
Tinker.Builder's constructor throws TinkerRuntimeException("Context must not be null.") when passed a null Context. The builder immediately uses the context to detect the current process and compute the patch directory, so a null context cannot be deferred; the guard fails fast at construction rather than later during build().
Source
Thrown at tinker-android/tinker-android-lib-no-op/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java:299
private final Context context;
private final boolean mainProcess;
private final boolean patchProcess;
private int status = -1;
private LoadReporter loadReporter;
private PatchReporter patchReporter;
private PatchListener listener;
private File patchDirectory;
private File patchInfoFile;
private File patchInfoLockFile;
private Boolean tinkerLoadVerifyFlag;
/**
* Start building a new {@link Tinker} instance.
*/
public Builder(Context context) {
if (context == null) {
throw new TinkerRuntimeException("Context must not be null.");
}
this.context = context;
this.mainProcess = TinkerServiceInternals.isInMainProcess(context);
this.patchProcess = TinkerServiceInternals.isInTinkerPatchServiceProcess(context);
this.patchDirectory = SharePatchFileUtil.getPatchDirectory(context);
if (this.patchDirectory == null) {
ShareTinkerLog.e(TAG, "patchDirectory is null!");
return;
}
this.patchInfoFile = SharePatchFileUtil.getPatchInfoFile(patchDirectory.getAbsolutePath());
this.patchInfoLockFile = SharePatchFileUtil.getPatchInfoLockFile(patchDirectory.getAbsolutePath());
ShareTinkerLog.w(TAG, "tinker patch directory: %s", patchDirectory);
}
public Builder tinkerFlags(int tinkerFlags) {
if (this.status != -1) {
throw new TinkerRuntimeException("tinkerFlag is already set.");
}View on GitHub (pinned to 1b7ea02c23)
Solutions
- Pass the application context obtained in attachBaseContext/onCreate (or ApplicationLike.getApplication()) — never an uninitialized field.
- Null-check the context at the call site with a clear error naming the caller when migrating old code.
- In unit tests, use RuntimeEnvironment.application (Robolectric) rather than null.
Example fix
// before
public class MyApp extends Application {
private final Tinker.Builder b = new Tinker.Builder(context); // field init: context null
// after
public class MyApp extends Application {
private Tinker.Builder b;
@Override public void onCreate() {
super.onCreate();
b = new Tinker.Builder(getApplicationContext());
}
} Defensive patterns
Strategy: validation
Validate before calling
Context ctx = (application != null) ? application.getApplicationContext() : null;
if (ctx == null) throw new IllegalStateException("no context for Tinker init");
Tinker.Builder builder = new Tinker.Builder(ctx); Prevention
- Never build Tinker config from field initializers; build it in onCreate/attachBaseContext
- Pass getApplicationContext(), not captured nullable fields
When it happens
Trigger: new Tinker.Builder(null) — typically because the context field was not yet assigned (call from a constructor or static init before onCreate), or a helper received null and forwarded it.
Common situations: Custom Application subclasses calling the builder before super.onCreate()/attachBaseContext finished setting up fields; test harnesses passing a null or mocked-null context; refactor moving Tinker init into a class whose context argument became optional.
Related errors
- tinkerLoadVerifyFlag must not be null.
- loadReporter must not be null.
- patchReporter must not be null.
- Context must not be null.
- tinkerLoadVerifyFlag must not be null.
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/cd3aa4f848ff5e34.
Report an issue: GitHub.