{"record":{"id":"fadfe1925ed17157","repo":"spring-projects/spring-boot","slug":"each-image-building-cache-can-be-configured-only-o","errorCode":null,"errorMessage":"Each image building cache can be configured only once","messagePattern":"Each image building cache can be configured only once","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/CacheSpec.java","lineNumber":59,"sourceCode":"\n\tprivate @Nullable Cache cache;\n\n\t@Inject\n\tpublic CacheSpec(ObjectFactory objectFactory) {\n\t\tthis.objectFactory = objectFactory;\n\t}\n\n\tpublic @Nullable Cache asCache() {\n\t\treturn this.cache;\n\t}\n\n\t/**\n\t * Configures a volume cache using the given {@code action}.\n\t * @param action the action\n\t */\n\tpublic void volume(Action<VolumeCacheSpec> action) {\n\t\tif (this.cache != null) {\n\t\t\tthrow new GradleException(\"Each image building cache can be configured only once\");\n\t\t}\n\t\tVolumeCacheSpec spec = this.objectFactory.newInstance(VolumeCacheSpec.class);\n\t\taction.execute(spec);\n\t\tthis.cache = Cache.volume(spec.getName().get());\n\t}\n\n\t/**\n\t * Configures a bind cache using the given {@code action}.\n\t * @param action the action\n\t */\n\tpublic void bind(Action<BindCacheSpec> action) {\n\t\tif (this.cache != null) {\n\t\t\tthrow new GradleException(\"Each image building cache can be configured only once\");\n\t\t}\n\t\tBindCacheSpec spec = this.objectFactory.newInstance(BindCacheSpec.class);\n\t\taction.execute(spec);\n\t\tthis.cache = Cache.bind(spec.getSource().get());\n\t}","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/270dfe353fb830fd69b823a8a859287ff103854b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/CacheSpec.java#L41-L77","documentation":"Thrown by CacheSpec.volume when this.cache is already non-null, meaning a cache configuration method (volume, bind, or image) has already been called on this CacheSpec. Each CacheSpec can configure exactly one cache type; calling a second method throws. This is the volume() entry point — the first of the three mutually exclusive cache configurators.","triggerScenarios":"Calling cache.volume { } after already calling cache.volume { }, cache.bind { }, or cache.image { } on the same CacheSpec instance within a bootBuildImage task configuration block.","commonSituations":"Copy-pasting DSL blocks that each configure a different cache type. Migrating from a volume cache to a bind cache and forgetting to remove the old block. Misunderstanding that only one cache type is allowed per CacheSpec.","solutions":["Keep only one cache configuration block (volume, bind, or image) per CacheSpec in your bootBuildImage configuration.","Audit the build script for duplicate cache { volume/bind/image } calls and remove all but one.","If you need different caches for different purposes, they must be on separate CacheSpec instances (e.g. different builder phases), not the same one."],"exampleFix":"// before\ntasks.bootBuildImage {\n    cache {\n        volume { name = \"my-cache\" }\n        bind { source = \"/tmp/cache\" }  // throws\n    }\n}\n// after\ntasks.bootBuildImage {\n    cache {\n        bind { source = \"/tmp/cache\" }\n    }\n}","handlingStrategy":"validation","validationCode":"// Track cache configuration count in your build script and assert uniqueness.\ndef cacheTypes = []\ntasks.bootBuildImage {\n    cache {\n        // only call ONE of: volume {}, bind {}, image {}\n        if (cacheTypes) throw new GradleException(\"Cache already configured: \" + cacheTypes)\n        cacheTypes << 'volume'\n        volume { name = \"my-cache\" }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure exactly one cache type per CacheSpec (volume, bind, or image).","Audit build scripts after refactoring cache configuration.","When migrating cache types, remove the old block before adding the new one."],"tags":["gradle","validation","build-image","cache","configuration","mutually-exclusive"],"backgroundTag":null,"analyzedSha":"270dfe353fb830fd69b823a8a859287ff103854b","analyzedAt":"2026-08-11T19:42:06.541Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}