{"record":{"id":"af431c4b177955f3","repo":"didi/DoKit","slug":"memory-cache-already-set","errorCode":null,"errorMessage":"Memory cache already set.","messagePattern":"Memory cache already set\\.","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java","lineNumber":753,"sourceCode":"     */\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;\n      return this;\n    }\n\n    /** Specify the memory cache used for the most recent images. */\n    public Builder memoryCache(Cache memoryCache) {\n      if (memoryCache == null) {\n        throw new IllegalArgumentException(\"Memory cache must not be null.\");\n      }\n      if (this.cache != null) {\n        throw new IllegalStateException(\"Memory cache already set.\");\n      }\n      this.cache = memoryCache;\n      return this;\n    }\n\n    /** Specify a listener for interesting events. */\n    public Builder listener(Listener listener) {\n      if (listener == null) {\n        throw new IllegalArgumentException(\"Listener must not be null.\");\n      }\n      if (this.listener != null) {\n        throw new IllegalStateException(\"Listener already set.\");\n      }\n      this.listener = listener;\n      return this;\n    }\n\n    /**","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java#L735-L771","documentation":"DokitPicasso.Builder.memoryCache() throws IllegalStateException when a Cache has already been assigned. The builder treats the memory cache as single-assignment so a misconfigured pipeline fails loudly instead of quietly swapping caches.","triggerScenarios":"Calling builder.memoryCache(...) a second time on the same Builder, e.g. a default LruCache set in shared code and a tuned cache set later.","commonSituations":"Two init layers (library default + app override) both configuring the cache; copy-pasted setup blocks after a cache-size refactor.","solutions":["Keep exactly one memoryCache() call per Builder","Move cache selection into a single helper that decides which cache to install","Rebuild from a new Builder when the full configuration must change"],"exampleFix":"// before\nbuilder.memoryCache(new LruCache(1024));\nbuilder.memoryCache(new LruCache(context)); // IllegalStateException\n\n// after\nbuilder.memoryCache(new LruCache(context));","handlingStrategy":"validation","validationCode":"// choose the cache first, then a single memoryCache() call\nCache chosen = useDefault ? new LruCache(context) : new LruCache(customBytes);\nbuilder.memoryCache(chosen);","typeGuard":null,"tryCatchPattern":"try { builder.memoryCache(c); } catch (IllegalStateException e) { if (!e.getMessage().contains(\"Memory cache already set\")) throw e; }","preventionTips":["Select the cache instance before configuring the builder, then call memoryCache() once"],"tags":["android","picasso","builder","configuration","cache"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}