{"record":{"id":"c3b8d8b64a6217f6","repo":"Tencent/tinker","slug":"target-is-null","errorCode":null,"errorMessage":"target is null.","messagePattern":"target is null\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/hotplug/interceptor/ServiceBinderInterceptor.java","lineNumber":69,"sourceCode":"\n    public ServiceBinderInterceptor(Context context, String serviceName, BinderInvocationHandler binderInvocationHandler) {\n        while (context != null && context instanceof ContextWrapper) {\n            context = ((ContextWrapper) context).getBaseContext();\n        }\n        mBaseContext = context;\n        mServiceName = serviceName;\n        mBinderInvocationHandler = binderInvocationHandler;\n    }\n\n    @Override\n    protected IBinder fetchTarget() throws Throwable {\n        return (IBinder) sGetServiceMethod.invoke(null, mServiceName);\n    }\n\n    @Override\n    protected IBinder decorate(IBinder target) throws Throwable {\n        if (target == null) {\n            throw new IllegalStateException(\"target is null.\");\n        }\n        if (ITinkerHotplugProxy.class.isAssignableFrom(target.getClass())) {\n            // Already intercepted, just return the target.\n            return target;\n        } else {\n            return createProxy(getAllInterfacesThroughDeriveChain(target.getClass()),\n                    new FakeClientBinderHandler(target, mBinderInvocationHandler));\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    protected void inject(IBinder decorated) throws Throwable {\n        final Map<String, IBinder> sCache = (Map<String, IBinder>) sSCacheField.get(null);\n        sCache.put(mServiceName, decorated);\n        if (Context.ACTIVITY_SERVICE.equals(mServiceName)) {\n            fixAMSBinderCache(decorated);\n        } else if (EnvConsts.PACKAGE_MANAGER_SRVNAME.equals(mServiceName)) {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/hotplug/interceptor/ServiceBinderInterceptor.java#L51-L87","documentation":"ServiceBinderInterceptor.decorate() wraps the IBinder fetched from ServiceManager.getService(serviceName) in a proxy. It throws IllegalStateException('target is null.') when that lookup returned null — the named system service is not currently registered, so there is nothing to intercept.","triggerScenarios":"fetchTarget() invoking ServiceManager.getService for a service that is not yet published (early boot, service restart) or that does not exist on the device (wrong service name, OEM removed it).","commonSituations":"Intercepting services during Application attachBaseContext before system services are up; typos in the service name; targeting a service absent on the specific ROM.","solutions":["Verify the exact service name against ServiceManager.listServices() on the target device.","Defer the interception until the service is registered (retry after onServiceRegistered / slight delay via lifecycle, not tight loop).","Treat a null target as 'nothing to intercept' and skip decoration instead of crashing."],"exampleFix":"// before\nIBinder binder = ServiceManager.getService(name); // may be null early\n\n// after\nIBinder binder = ServiceManager.getService(name);\nif (binder == null) {\n    // service not yet published; defer interception\n    return;\n}","handlingStrategy":"validation","validationCode":"IBinder binder = (IBinder) sGetServiceMethod.invoke(null, mServiceName);\nif (binder == null) {\n    // service not published yet: defer interception, do not decorate\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    interceptor.decorate(binder);\n} catch (IllegalStateException e) {\n    // target null: retry later when the service is registered\n}","preventionTips":["Check the service exists via ServiceManager.listServices() before intercepting.","Defer interception until first actual use of the service, not at app start.","Spell service names exactly as in the framework (e.g. 'activity', 'package')."],"tags":["android","binder","servicemanager","interceptor","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}