{"record":{"id":"e308ba734fd8ce09","repo":"didi/DoKit","slug":"requesthandler-already-registered","errorCode":null,"errorMessage":"RequestHandler already registered.","messagePattern":"RequestHandler already registered\\.","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java","lineNumber":797,"sourceCode":"        throw new IllegalArgumentException(\"Transformer must not be null.\");\n      }\n      if (this.transformer != null) {\n        throw new IllegalStateException(\"Transformer already set.\");\n      }\n      this.transformer = transformer;\n      return this;\n    }\n\n    /** Register a {@link RequestHandler}. */\n    public Builder addRequestHandler(RequestHandler requestHandler) {\n      if (requestHandler == null) {\n        throw new IllegalArgumentException(\"RequestHandler must not be null.\");\n      }\n      if (requestHandlers == null) {\n        requestHandlers = new ArrayList<RequestHandler>();\n      }\n      if (requestHandlers.contains(requestHandler)) {\n        throw new IllegalStateException(\"RequestHandler already registered.\");\n      }\n      requestHandlers.add(requestHandler);\n      return this;\n    }\n\n    /**\n     * @deprecated Use {@link #indicatorsEnabled(boolean)} instead.\n     * Whether debugging is enabled or not.\n     */\n    @Deprecated public Builder debugging(boolean debugging) {\n      return indicatorsEnabled(debugging);\n    }\n\n    /** Toggle whether to display debug indicators on images. */\n    public Builder indicatorsEnabled(boolean enabled) {\n      this.indicatorsEnabled = enabled;\n      return this;\n    }","sourceCodeStart":779,"sourceCodeEnd":815,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java#L779-L815","documentation":"DokitPicasso.Builder.addRequestHandler() throws IllegalStateException when the exact same RequestHandler instance is registered twice. The builder tracks registered handlers by identity to avoid duplicate handler consultation and double work during request resolution.","triggerScenarios":"Calling builder.addRequestHandler(h) twice with the same instance, e.g. a shared handler singleton registered by both library init and app init.","commonSituations":"Initialization code run more than once (activity re-entry into an init method); a singleton handler registered in a loop over modules where two modules share it.","solutions":["Register each handler instance exactly once; dedupe with a Set before registering","Make init idempotent so the builder path only runs one time","If re-registration is intended, create a new handler instance or skip when already present"],"exampleFix":"// before\nSet<RequestHandler> registered = new HashSet<>();\nfor (RequestHandler h : handlers) {\n  builder.addRequestHandler(h); // IllegalStateException on duplicate instance\n}\n\n// after\nSet<RequestHandler> unique = new LinkedHashSet<>(handlers);\nfor (RequestHandler h : unique) {\n  builder.addRequestHandler(h);\n}","handlingStrategy":"validation","validationCode":"Set<RequestHandler> unique = new LinkedHashSet<>(handlers);\nfor (RequestHandler h : unique) { builder.addRequestHandler(h); }","typeGuard":null,"tryCatchPattern":"try { builder.addRequestHandler(h); } catch (IllegalStateException e) { if (!e.getMessage().contains(\"RequestHandler already registered\")) throw e; }","preventionTips":["Dedupe handlers by instance identity before registering","Make Picasso initialization run exactly once (guard with a boolean or singleton)"],"tags":["android","picasso","builder","configuration","duplicate"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}