{"record":{"id":"64df7fad0fb7c385","repo":"spring-projects/spring-ai","slug":"anthropic-cache-breakpoint-limit-4-reached-addi","errorCode":null,"errorMessage":"Anthropic cache breakpoint limit (4) reached. Additional cache_control directives will be ignored. Consider using fewer cache strategies or simpler content structure.","messagePattern":"Anthropic cache breakpoint limit \\(4\\) reached\\. Additional cache_control directives will be ignored\\. Consider using fewer cache strategies or simpler content structure\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/CacheBreakpointTracker.java","lineNumber":51,"sourceCode":"\n\tprivate int count = 0;\n\n\tprivate boolean hasWarned = false;\n\n\tpublic boolean canUse() {\n\t\treturn this.count < 4;\n\t}\n\n\tpublic boolean allBreakpointsAreUsed() {\n\t\treturn !this.canUse();\n\t}\n\n\tpublic void use() {\n\t\tif (this.count < 4) {\n\t\t\tthis.count++;\n\t\t}\n\t\telse if (!this.hasWarned) {\n\t\t\tlogger.warn(\n\t\t\t\t\t\"Anthropic cache breakpoint limit (4) reached. Additional cache_control directives will be ignored. \"\n\t\t\t\t\t\t\t+ \"Consider using fewer cache strategies or simpler content structure.\");\n\t\t\tthis.hasWarned = true;\n\t\t}\n\t}\n\n\tpublic int getCount() {\n\t\treturn this.count;\n\t}\n\n}\n","sourceCodeStart":33,"sourceCodeEnd":63,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/CacheBreakpointTracker.java#L33-L63","documentation":"A warning from CacheBreakpointTracker.use() when more than 4 cache_control breakpoints are requested in a single Anthropic request. The Anthropic API caps prompt caching at 4 breakpoints; the tracker stops counting and warns once that additional cache_control directives will be ignored, so those content parts will not be cached.","triggerScenarios":"Building a Prompt whose system text, messages, and/or tools collectively carry more than 4 CacheBreakpoint/ContentPart cache-control markers, then calling the chat model — each marker calls tracker.use(), and the 5th onward triggers the warning.","commonSituations":"Caching every tool definition plus system plus several history messages; combining multiple caching strategies (system, tools, conversation) without counting; generated prompts that add a breakpoint per message in long conversations.","solutions":["Reduce cache_control breakpoints to at most 4, placing them at the most stable, longest-lived boundaries (tools, system, earliest messages)","Move the single breakpoint to the last message instead of marking every message","Consolidate content: merge cached segments so fewer breakpoints cover more tokens","Audit prompt-building code for per-message breakpoint additions in loops","Suppress irrelevant directives on volatile content (short-lived messages) that does not benefit from caching"],"exampleFix":"// before\neachMessage.addCacheBreakpoint(); // >4 messages -> overflow ignored\n// after\n// put one breakpoint on last (stable) content to cover everything before it\nmessages.get(messages.size() - 1).addCacheBreakpoint();","handlingStrategy":"validation","validationCode":"// count cache breakpoints before building the request\nlong breakpoints = contentParts.stream().filter(ContentPart::hasCacheControl).count();\nif (breakpoints > 4) {\n    throw new IllegalArgumentException(\"Max 4 Anthropic cache breakpoints, got \" + breakpoints);\n}","typeGuard":null,"tryCatchPattern":"// warning only (no exception): detect via logging and adjust prompt construction\nif (logContains(\"cache breakpoint limit\")) {\n    // rebuild prompt with fewer cache_control markers\n}","preventionTips":["Cap cache_control markers at 4 per request; place them at stable boundaries (tools, system, oldest messages)","Use a single breakpoint on the last message to cache the entire prefix","Do not add a breakpoint per message in loops over conversation history","Exclude volatile content (recent messages) from caching","Review prompt-builder code when switching between caching strategies to avoid double-marking"],"tags":["anthropic","prompt-caching","cache-control","limits","spring-ai"],"backgroundTag":"value-out-of-range","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}