{"record":{"id":"f9e33506b1cafca4","repo":"Tencent/tinker","slug":"tinker-instance-is-already-set-f9e335","errorCode":null,"errorMessage":"Tinker instance is already set.","messagePattern":"Tinker instance is already set\\.","errorType":"exception","errorClass":"TinkerRuntimeException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java","lineNumber":125,"sourceCode":"            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.\");\n        }\n        sInstance = tinker;\n    }\n\n    public static boolean isTinkerInstalled() {\n        return sInstalled;\n    }\n\n    /**\n     * you must install tinker first!!\n     *\n     * @param intentResult\n     * @param serviceClass\n     * @param upgradePatch\n     */\n    public void install(Intent intentResult, Class<? extends AbstractResultService> serviceClass,\n                        AbstractPatch upgradePatch) {\n        sInstalled = true;","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/Tinker.java#L107-L143","documentation":"Tinker.create(tinker) explicitly initializes the singleton with a custom-built instance and enforces single invocation: a second call while sInstance != null throws. This prevents two different configurations from silently replacing each other.","triggerScenarios":"Calling Tinker.create(...) twice in one process, or mixing Tinker.create with the lazy path Tinker.with(...) — with() also populates sInstance, so calling create after any with() call throws.","commonSituations":"SDK modules or third-party wrappers that each try to initialize tinker; app calling create in onCreate while a library earlier obtained Tinker.with(context); process-wide init code that runs on configuration change or re-attach.","solutions":["Initialize tinker exactly once per process, in ApplicationLike.onCreate.","Guard with Tinker.isTinkerInstalled() / a static boolean before calling create.","If multiple modules need tinker, centralize ownership of initialization in the app module."],"exampleFix":"// before\nTinker.create(myTinker); // module A\nTinker.create(theirTinker); // module B -> throws\n\n// after\nif (!Tinker.isTinkerInstalled()) {\n    Tinker.create(myTinker);\n}","handlingStrategy":"validation","validationCode":"synchronized (Tinker.class) {\n    if (!Tinker.isTinkerInstalled()) {\n        Tinker.create(customTinker);\n    }\n}","typeGuard":"public static boolean isTinkerSingletonPresent() {\n    return Tinker.isTinkerInstalled(); // with()/create both land on installed state\n}","tryCatchPattern":null,"preventionTips":["Centralize tinker initialization in one app-owned location.","Audit SDK modules for their own Tinker.create calls before integrating.","Do not mix Tinker.create with Tinker.with() lazy init in the same process."],"tags":["tinker","android","initialization","singleton","double-init"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}