{"record":{"id":"5e9f785266fa943f","repo":"didi/DoKit","slug":"transformer-already-set","errorCode":null,"errorMessage":"Transformer already set.","messagePattern":"Transformer already set\\.","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java","lineNumber":782,"sourceCode":"      if (this.listener != null) {\n        throw new IllegalStateException(\"Listener already set.\");\n      }\n      this.listener = listener;\n      return this;\n    }\n\n    /**\n     * Specify a transformer for all incoming requests.\n     * <p>\n     * <b>NOTE:</b> This is a beta feature. The API is subject to change in a backwards incompatible\n     * way at any time.\n     */\n    public Builder requestTransformer(RequestTransformer transformer) {\n      if (transformer == null) {\n        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;","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java#L764-L800","documentation":"DokitPicasso.Builder.requestTransformer() throws IllegalStateException when a RequestTransformer has already been set. The transformer slot is single-assignment, mirroring upstream Picasso where chaining two transformers is a configuration error.","triggerScenarios":"Calling builder.requestTransformer(...) twice on the same Builder, e.g. one transformer added by shared code and another by feature-specific code.","commonSituations":"Merging init paths after refactoring; a common module and an app module each installing their own URL-rewriting transformer.","solutions":["Combine both transformations into a single RequestTransformer and register it once","Delete the duplicate requestTransformer() call","Reconfigure from a new Builder if the pipeline must change wholesale"],"exampleFix":"// before\nbuilder.requestTransformer(new AuthTransformer());\nbuilder.requestTransformer(new CdnTransformer()); // IllegalStateException\n\n// after\nclass ChainedTransformer implements DokitPicasso.RequestTransformer {\n  ...apply auth then cdn...\n}\nbuilder.requestTransformer(new ChainedTransformer());","handlingStrategy":"validation","validationCode":"class Chained implements DokitPicasso.RequestTransformer { public Request transformRequest(Request r) { return second.transformRequest(first.transformRequest(r)); } }\nbuilder.requestTransformer(new Chained()); // single call","typeGuard":null,"tryCatchPattern":"try { builder.requestTransformer(t); } catch (IllegalStateException e) { if (!e.getMessage().contains(\"Transformer already set\")) throw e; }","preventionTips":["Chain transformations inside one transformer instead of registering several"],"tags":["android","picasso","builder","configuration"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}