Tencent/tinker · error · TinkerRuntimeException

tinkerLoadVerifyFlag must not be null.

Error message

tinkerLoadVerifyFlag must not be null.

What it means

Tinker.Builder.tinkerLoadVerifyFlag(Boolean) throws TinkerRuntimeException("tinkerLoadVerifyFlag must not be null.") when passed a null Boolean. The flag controls whether patch files are md5-verified at load time, so it must be a definite true/false decision; the builder distinguishes 'not yet set' (null field) from 'set' and requires an explicit value, rejecting null arguments including Boolean variables that were never assigned.

Source

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

                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.");
            }
            this.status = tinkerFlags;
            return this;
        }

        public Builder tinkerLoadVerifyFlag(Boolean verifyMd5WhenLoad) {
            if (verifyMd5WhenLoad == null) {
                throw new TinkerRuntimeException("tinkerLoadVerifyFlag must not be null.");
            }
            if (this.tinkerLoadVerifyFlag != null) {
                throw new TinkerRuntimeException("tinkerLoadVerifyFlag is already set.");
            }
            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;
        }

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Default the value explicitly before the call: Boolean verify = (cfgFlag != null) ? cfgFlag : Boolean.FALSE; then pass it.
  2. If the source is BuildConfig, define the field in every flavor or use a constant.
  3. Log the resolved value during init to catch null sources early in QA builds.

Example fix

// before
Boolean verify = configMap.get("verifyPatchOnLoad"); // null when key missing
builder.tinkerLoadVerifyFlag(verify); // throws

// after
Boolean raw = configMap.get("verifyPatchOnLoad");
builder.tinkerLoadVerifyFlag(raw != null ? raw : Boolean.FALSE);
Defensive patterns

Strategy: validation

Validate before calling

Boolean raw = config.get("tinkerLoadVerifyFlag");
boolean verify = (raw != null) ? raw : false; // explicit default
builder.tinkerLoadVerifyFlag(verify);

Prevention

When it happens

Trigger: Calling tinkerLoadVerifyFlag(null) — typically a Boolean read from a config map, BuildConfig field, or intent extra that is absent in the current build/variant, or a boxed variable defaulted to null.

Common situations: Reading the flag from a JSON/config file where the key is missing in some environments; flavor-specific BuildConfig fields not defined in all variants; deserialized preferences returning null after a schema change.

Related errors


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