{"record":{"id":"d401d63f5d5ea20b","repo":"Tencent/tinker","slug":"you-must-install-tinker-before-get-tinker-sinstanc","errorCode":null,"errorMessage":"you must install tinker before get tinker sInstance","messagePattern":"you must install tinker before get tinker sInstance","errorType":"exception","errorClass":"TinkerRuntimeException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-lib-no-op/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java","lineNumber":101,"sourceCode":"        this.tinkerFlags = tinkerFlags;\n        this.patchDirectory = patchDirectory;\n        this.patchInfoFile = patchInfoFile;\n        this.patchInfoLockFile = patchInfoLockFile;\n        this.isMainProcess = isInMainProc;\n        this.tinkerLoadVerifyFlag = tinkerLoadVerifyFlag;\n        this.isPatchProcess = isPatchProcess;\n    }\n\n    /**\n     * init with default config tinker\n     * for safer, you must use @{link TinkerInstaller.install} first!\n     *\n     * @param context we will use the application context\n     * @return the Tinker object\n     */\n    public static Tinker with(Context context) {\n        if (!sInstalled) {\n            throw new TinkerRuntimeException(\"you must install tinker before get tinker sInstance\");\n        }\n        synchronized (Tinker.class) {\n            if (sInstance == null) {\n                sInstance = new Builder(context).build();\n            }\n        }\n        return sInstance;\n    }\n\n    /**\n     * create custom tinker by {@link Tinker.Builder}\n     * please do it when very first your app start.\n     *\n     * @param tinker\n     */\n    public static void create(Tinker tinker) {\n        if (sInstance != null) {\n            throw new TinkerRuntimeException(\"Tinker instance is already set.\");","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-lib-no-op/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java#L83-L119","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npublic void onCreate() {\n    super.onCreate();\n    Tinker.with(this).getTinkerLoadResultIfWithPatch(); // throws\n    TinkerInstaller.install(appLike, ...);\n}\n\n// after\npublic void onCreate() {\n    super.onCreate();\n    TinkerInstaller.install(appLike, loadReport, patchReport, patchListener, ...);\n    if (Tinker.isTinkerInstalled()) {\n        Tinker.with(this).getTinkerLoadResultIfWithPatch();\n    }\n}","handlingStrategy":"validation","validationCode":"if (Tinker.isTinkerInstalled()) {\n    Tinker tinker = Tinker.with(context);\n    // use tinker...\n} else {\n    Log.w(TAG, \"Tinker not installed; skipping Tinker.with()\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Tinker tinker = Tinker.with(context);\n} catch (TinkerRuntimeException e) {\n    // install was never called in this process\n    Log.w(TAG, \"Tinker.with before install\", e);\n}","preventionTips":["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"],"tags":["android","tinker","initialization","singleton","no-op"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}