Tencent/tinker · error · TinkerRuntimeException

patchReporter must not be null.

Error message

patchReporter must not be null.

What it means

Tinker.Builder.patchReporter(PatchReporter) throws TinkerRuntimeException("patchReporter must not be null.") when passed a null PatchReporter. The patch reporter receives patch-application callbacks (try patch, patch success/failure, rollback) and is mandatory in a Tinker configuration; the builder fails fast on null instead of leaving patch failures unreported.

Source

Thrown at tinker-android/tinker-android-lib-no-op/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java:346

            }
            this.tinkerLoadVerifyFlag = verifyMd5WhenLoad;
            return this;
        }

        public Builder loadReport(LoadReporter loadReporter) {
            if (loadReporter == null) {
                throw new TinkerRuntimeException("loadReporter must not be null.");
            }
            if (this.loadReporter != null) {
                throw new TinkerRuntimeException("loadReporter is already set.");
            }
            this.loadReporter = loadReporter;
            return this;
        }

        public Builder patchReporter(PatchReporter patchReporter) {
            if (patchReporter == null) {
                throw new TinkerRuntimeException("patchReporter must not be null.");
            }
            if (this.patchReporter != null) {
                throw new TinkerRuntimeException("patchReporter is already set.");
            }
            this.patchReporter = patchReporter;
            return this;
        }

        public Builder listener(PatchListener listener) {
            if (listener == null) {
                throw new TinkerRuntimeException("listener must not be null.");
            }
            if (this.listener != null) {
                throw new TinkerRuntimeException("listener is already set.");
            }
            this.listener = listener;
            return this;
        }

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Create the PatchReporter into a local (e.g. new DefaultPatchReporter(getApplicationContext())) and pass that; assert non-null before the chain.
  2. Order initialization so the Application context exists before building Tinker config.
  3. In tests use a no-op PatchReporter subclass rather than null.

Example fix

// before
builder.patchReporter(patchReporter); // field null at this point

// after
PatchReporter patchReporter = new DefaultPatchReporter(getApplicationContext());
builder.patchReporter(patchReporter);
Defensive patterns

Strategy: validation

Validate before calling

PatchReporter patchReporter = (customReporter != null)
        ? customReporter
        : new DefaultPatchReporter(getApplicationContext());
builder.patchReporter(patchReporter);

Prevention

When it happens

Trigger: Calling patchReporter(null) — a null field at chain time due to constructor ordering (reporter needs the Application, which is not ready), a flavor-specific reporter not created in that variant, or an argument dropped during refactor.

Common situations: Init code in attachBaseContext referencing a reporter field assigned only in onCreate; unit tests or demo samples omitting reporters; upgrading Tinker versions where constructor signatures changed and a reporter instantiation was removed.

Related errors


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