Tencent/tinker · error · TinkerRuntimeException
Context must not be null.
Error message
Context must not be null.
What it means
Tinker.Builder's constructor immediately rejects a null Context. The builder needs a Context to derive process identity (main vs :patch), the patch directory, and info files, so a null context makes the whole configuration meaningless and fails fast.
Source
Thrown at tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java:350
private final boolean mainProcess;
private final boolean patchProcess;
private int status = -1;
private LoadReporter loadReporter;
private PatchReporter patchReporter;
private PatchListener listener;
private AbstractFilePatch patcher;
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 applicationContext, and construct the Builder only after the context is attached.
- In ApplicationLike, create the builder in onCreate (not earlier lifecycle hooks) when in doubt.
- Add a null assertion upstream so the failure points at the real missing dependency.
Example fix
// before
public MyAppLike(Application app) {
this.builder = new Tinker.Builder(this.context); // context not yet set -> null
}
// after
@Override public void onCreate() {
this.builder = new Tinker.Builder(getApplication().getApplicationContext());
} Defensive patterns
Strategy: validation
Validate before calling
if (context == null) throw new IllegalArgumentException("context required before tinker init");
Tinker.Builder builder = new Tinker.Builder(context.getApplicationContext()); Type guard
public static boolean isValidContext(Context c) {
return c != null && c.getApplicationContext() != null;
} Prevention
- Build the Tinker.Builder in ApplicationLike.onCreate when the context is guaranteed attached.
- Always pass getApplicationContext(), never a nullable field.
- In tests, use Robolectric to supply a real Context.
When it happens
Trigger: Constructing new Tinker.Builder(null) — usually because a Context field was not yet assigned (constructor ordering), a DI-provided context was null, or a test passed null.
Common situations: Custom ApplicationLike subclasses that build a Tinker in onBaseContextAttached before attachBaseContext finishes; unit tests without Robolectric; refactor moving builder creation before context initialization.
Related errors
- Context must not be null.
- tinkerLoadVerifyFlag must not be null.
- loadReporter must not be null.
- patchReporter must not be null.
- tinkerLoadVerifyFlag must not be null.
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/3a22381eec373eba.
Report an issue: GitHub.