{"record":{"id":"90e74c60b4a3fd60","repo":"JuliusBrussee/caveman","slug":"cacheengine-stable-prefix-exceeds-configured-byte","errorCode":null,"errorMessage":"cacheengine: stable prefix exceeds configured byte limit","messagePattern":"cacheengine: stable prefix exceeds configured byte limit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cacheengine/engine.go","lineNumber":339,"sourceCode":"}\n\nfunc stablePrefix(segments []Segment, maxBytes int) ([]byte, []Segment, error) {\n\tvar prefix []byte\n\tvar stable []Segment\n\tseenNames := map[string]bool{}\n\tfor _, segment := range segments {\n\t\tif !segment.Stable || !segment.Cacheable {\n\t\t\tbreak\n\t\t}\n\t\tif !validIdentity(segment.Name, 1024, false) || len(segment.Content) == 0 || seenNames[segment.Name] {\n\t\t\treturn nil, nil, errors.New(\"cacheengine: stable segment needs name and content\")\n\t\t}\n\t\tseenNames[segment.Name] = true\n\t\tif segment.Tokens < 0 || segment.ExpectedCalls < 0 {\n\t\t\treturn nil, nil, errors.New(\"cacheengine: negative segment measurement\")\n\t\t}\n\t\tif maxBytes < 8 || len(segment.Name) > maxBytes-8 || len(segment.Content) > maxBytes-8-len(segment.Name) || len(prefix) > maxBytes-8-len(segment.Name)-len(segment.Content) {\n\t\t\treturn nil, nil, errors.New(\"cacheengine: stable prefix exceeds configured byte limit\")\n\t\t}\n\t\tif len(segment.Name) > math.MaxUint32 || len(segment.Content) > math.MaxUint32 {\n\t\t\treturn nil, nil, errors.New(\"cacheengine: segment exceeds framing limit\")\n\t\t}\n\t\tprefix = appendFrame(prefix, segment.Name, segment.Content)\n\t\tstable = append(stable, segment)\n\t}\n\treturn prefix, stable, nil\n}\n\nfunc appendFrame(dst []byte, name string, content []byte) []byte {\n\tvar lengths [8]byte\n\tbinary.BigEndian.PutUint32(lengths[:4], uint32(len(name)))\n\tbinary.BigEndian.PutUint32(lengths[4:], uint32(len(content)))\n\tdst = append(dst, lengths[:]...)\n\tdst = append(dst, name...)\n\treturn append(dst, content...)\n}","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/cacheengine/engine.go#L321-L357","documentation":"Thrown by stablePrefix when the framed prefix cannot fit in maxBytes: the limit itself is below 8 (framing header size), or name+content of the current segment, or the accumulated prefix plus the segment, would exceed maxBytes-8. Each segment costs 8 bytes of length framing plus name plus content.","triggerScenarios":"Calling Plan with a small configured byte limit (or 0/unset) while stable segments are large; growing the stable prefix segment-by-segment until the cumulative framed size passes the configured cap; maxBytes < 8 makes every input fail.","commonSituations":"Forgetting to configure the byte limit so it defaults to something tiny (or zero); raising prompt content without raising the provider prefix limit; adding another stable document block to a prefix already near the cap.","solutions":["Raise the configured maxBytes to fit the full stable prefix (remember +8 framing bytes per segment)","Trim or shrink stable segment content (fewer/fresher documents) so the framed prefix fits","If maxBytes < 8 in your config, it is invalid for any use — fix the configuration value"],"exampleFix":"// before\nengine := cacheengine.New(cfg) // cfg.MaxPrefixBytes left at 0 -> any stable segment fails\n\n// after\ncfg.MaxPrefixBytes = 64 * 1024 // comfortably above sum(len(name)+len(content)+8) of all stable segments\nengine := cacheengine.New(cfg)","handlingStrategy":"validation","validationCode":"func framedPrefixSize(segs []cacheengine.Segment) int {\n    n := 0\n    for _, s := range segs {\n        if !s.Stable || !s.Cacheable { break }\n        n += 8 + len(s.Name) + len(s.Content)\n    }\n    return n\n}\n// require framedPrefixSize(segs) <= cfg.MaxPrefixBytes && cfg.MaxPrefixBytes >= 8","typeGuard":"// n/a","tryCatchPattern":null,"preventionTips":["Budget 8 framing bytes per segment when sizing the limit","Re-check the limit whenever you add another stable document block"],"tags":["cacheengine","limits","prefix","configuration","go"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}