{"record":{"id":"3cd8607450ac424f","repo":"didi/DoKit","slug":"downloader-already-set","errorCode":null,"errorMessage":"Downloader already set.","messagePattern":"Downloader already set\\.","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java","lineNumber":725,"sourceCode":"    /**\n     * Specify the default {@link Bitmap.Config} used when decoding images. This can be overridden\n     * on a per-request basis using {@link RequestCreator#config(Bitmap.Config) config(..)}.\n     */\n    public Builder defaultBitmapConfig(Bitmap.Config bitmapConfig) {\n      if (bitmapConfig == null) {\n        throw new IllegalArgumentException(\"Bitmap config must not be null.\");\n      }\n      this.defaultBitmapConfig = bitmapConfig;\n      return this;\n    }\n\n    /** Specify the {@link Downloader} that will be used for downloading images. */\n    public Builder downloader(Downloader downloader) {\n      if (downloader == null) {\n        throw new IllegalArgumentException(\"Downloader must not be null.\");\n      }\n      if (this.downloader != null) {\n        throw new IllegalStateException(\"Downloader already set.\");\n      }\n      this.downloader = downloader;\n      return this;\n    }\n\n    /**\n     * Specify the executor service for loading images in the background.\n     * <p>\n     * Note: Calling {@link DokitPicasso#shutdown() shutdown()} will not shutdown supplied executors.\n     */\n    public Builder executor(ExecutorService executorService) {\n      if (executorService == null) {\n        throw new IllegalArgumentException(\"Executor service must not be null.\");\n      }\n      if (this.service != null) {\n        throw new IllegalStateException(\"Executor service already set.\");\n      }\n      this.service = executorService;","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java#L707-L743","documentation":"DokitPicasso.Builder.downloader() throws IllegalStateException when a Downloader has already been assigned to this builder. The builder enforces one-shot configuration for each component to avoid silently replacing a configured downloader. This mirrors upstream Picasso's builder contract.","triggerScenarios":"Calling builder.downloader(d) a second time on the same Builder instance, e.g. applying a default downloader and then overriding it with a custom OkHttp downloader.","commonSituations":"Copy-pasted configuration code that sets a downloader in two places; a shared builder passed through several config methods; upgrading code that injected a new downloader without removing the old call.","solutions":["Remove the duplicate downloader() call so it is invoked exactly once per Builder","If you need to replace a downloader, create a fresh Builder and configure it once","Track whether the builder was already configured before calling downloader() again"],"exampleFix":"// before\nbuilder.downloader(defaultDownloader);\nbuilder.downloader(new OkHttp3Downloader(client)); // IllegalStateException\n\n// after\nbuilder.downloader(new OkHttp3Downloader(client));","handlingStrategy":"validation","validationCode":"// Set the downloader exactly once; track it yourself\nif (builderHasDownloader) { throw new IllegalStateException(\"configure downloader once\"); }\nbuilder.downloader(new OkHttp3Downloader(client));\nbuilderHasDownloader = true;","typeGuard":null,"tryCatchPattern":"try { builder.downloader(d); } catch (IllegalStateException e) { if (!e.getMessage().contains(\"Downloader already set\")) throw e; log(\"downloader already configured\"); }","preventionTips":["Build the entire Picasso configuration in one method so each component is set exactly once","Never share a Builder across init layers without ownership rules","Treat builder IllegalStateExceptions as programming errors to fix, not to catch"],"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"}