JuliusBrussee/caveman · error
cacheengine: stable segment needs name and content
Error message
cacheengine: stable segment needs name and content
What it means
Thrown by stablePrefix while folding the leading run of Stable && Cacheable segments: a segment must have a valid non-empty Name (<= 1024 bytes, identity rules), non-empty Content, and a Name not seen earlier in the prefix. The loop stops at the first non-stable/non-cacheable segment, so only the head of the segment list is affected.
Source
Thrown at cacheengine/engine.go:332
if profile.MaxRPMPerKey == 0 {
profile.MaxRPMPerKey = 15
}
if profile.Attribution == "" {
profile.Attribution = AttributionNone
}
return profile
}
func stablePrefix(segments []Segment, maxBytes int) ([]byte, []Segment, error) {
var prefix []byte
var stable []Segment
seenNames := map[string]bool{}
for _, segment := range segments {
if !segment.Stable || !segment.Cacheable {
break
}
if !validIdentity(segment.Name, 1024, false) || len(segment.Content) == 0 || seenNames[segment.Name] {
return nil, nil, errors.New("cacheengine: stable segment needs name and content")
}
seenNames[segment.Name] = true
if segment.Tokens < 0 || segment.ExpectedCalls < 0 {
return nil, nil, errors.New("cacheengine: negative segment measurement")
}
if 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) {
return nil, nil, errors.New("cacheengine: stable prefix exceeds configured byte limit")
}
if len(segment.Name) > math.MaxUint32 || len(segment.Content) > math.MaxUint32 {
return nil, nil, errors.New("cacheengine: segment exceeds framing limit")
}
prefix = appendFrame(prefix, segment.Name, segment.Content)
stable = append(stable, segment)
}
return prefix, stable, nil
}
func appendFrame(dst []byte, name string, content []byte) []byte {View on GitHub (pinned to 27d5a3981a)
Solutions
- Give every stable cacheable segment a unique, non-empty, <= 1024-byte identity-safe Name
- Ensure Content is non-empty for each stable segment (skip the segment instead of sending it empty)
- Deduplicate names by indexing them (e.g. 'context-1', 'context-2') if you legitimately repeat a kind of segment
Example fix
// before
segments := []cacheengine.Segment{{Name: "docs", Stable: true, Cacheable: true, Content: nil}}
// after
segments := []cacheengine.Segment{{Name: "docs-v2", Stable: true, Cacheable: true, Content: docBytes}} Defensive patterns
Strategy: validation
Validate before calling
func stableSegmentsOK(segs []cacheengine.Segment) error {
seen := map[string]bool{}
for _, s := range segs {
if !s.Stable || !s.Cacheable { break }
if s.Name == "" || len(s.Name) > 1024 || len(s.Content) == 0 || seen[s.Name] { return fmt.Errorf("bad segment %q", s.Name) }
seen[s.Name] = true
}
return nil
} Type guard
func isStableSegment(s cacheengine.Segment) bool { return s.Stable && s.Cacheable && s.Name != "" && len(s.Content) > 0 } Prevention
- Generate names deterministically from content identity (e.g. hash) to guarantee uniqueness
- Skip empty segments instead of sending them
When it happens
Trigger: Passing Segments where a leading stable/cacheable segment has Name == "" (or > 1024 bytes / bad charset), Content of zero length, or two leading stable segments sharing the same Name.
Common situations: Generating segment names from user content that can be empty; reusing a constant name like 'context' for multiple stable segments; forgetting that the system/description segment must carry content; whitespace-trimmed content becoming empty.
Related errors
- cacheengine: invalid partition key
- cacheengine: negative traffic expectation
- cacheengine: invalid profile identity
- cacheengine: invalid cache thresholds
- cacheengine: invalid cache economics
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/693b8077a33564df.
Report an issue: GitHub.