JuliusBrussee/caveman · error · ErrMemoryTooLarge
ErrMemoryTooLarge
ErrMemoryTooLarge
Error message
%w: memory is %d bytes, over the %d-byte cap
What it means
Returned by validateMemorySize when the text passed to Remember/Supersede exceeds MaxMemoryBytes (256 KiB). The store deliberately fails closed with the sentinel ErrMemoryTooLarge (surfaced as cave_memoryTooLarge / CLI exit 65) because a memory is a recallable fact, not a file dump. The wrapper text includes the offending size and the cap so you can see how far over you are.
Source
Thrown at mem/store.go:270
}
if n, _ := res.RowsAffected(); n != 1 {
return Memory{}, fmt.Errorf("memory %s changed during supersede", oldID)
}
if err := tx.Commit(); err != nil {
return Memory{}, fmt.Errorf("supersede commit: %w", err)
}
return Memory{
ID: newID,
Text: newText,
CreatedAt: now,
ValidFrom: now,
Supersedes: oldID,
}, nil
}
func validateMemorySize(text string) error {
if len(text) > MaxMemoryBytes {
return fmt.Errorf("%w: memory is %d bytes, over the %d-byte cap", ErrMemoryTooLarge, len(text), MaxMemoryBytes)
}
return nil
}
// History returns the complete oldest-to-newest supersession chain containing
// id. Broken/cyclic lineage is rejected rather than returning partial history.
func (s *Store) History(id string) ([]Memory, error) {
if strings.TrimSpace(id) == "" {
return nil, fmt.Errorf("history requires memory id")
}
current, err := s.memoryByID(id)
if err != nil {
return nil, err
}
seen := map[string]bool{current.ID: true}
var before []Memory
cursor := current
for cursor.Supersedes != "" {View on GitHub (pinned to 27d5a3981a)
Solutions
- Split the content into multiple memories under 256 KiB each, or store a summary/reference and keep the full payload elsewhere
- Truncate deliberately before calling Remember if only a prefix matters, after measuring len(text)
- If you truly need unlimited single memories, that is not supported by design — reconsider what you are storing
Example fix
// before
err := store.Remember(string(fileContents)) // 1 MB file -> ErrMemoryTooLarge
// after
const chunk = 200 * 1024
for len(text) > 0 {
n := min(chunk, len(text))
if err := store.Remember(text[:n]); err != nil { return err }
text = text[n:]
} Defensive patterns
Strategy: validation
Validate before calling
if err := mem.ValidateSize(text); err != nil { // or: if len(text) > mem.MaxMemoryBytes
return err
}
err := store.Remember(text) Type guard
func fitsMemoryCap(text string) bool { return len(text) <= mem.MaxMemoryBytes } Try / catch
err := store.Remember(text)
if err != nil {
if errors.Is(err, mem.ErrMemoryTooLarge) {
// split, summarize, or truncate before retrying once
}
return err
} Prevention
- Measure len(text) at the boundary where untrusted/large input enters (file reads, HTTP bodies)
- Chunk or summarize large payloads instead of storing them whole
- Check errors.Is(err, mem.ErrMemoryTooLarge) rather than string matching — it is a sentinel
- CLI callers exit 65 on this error; wrappers should map it, not swallow it
When it happens
Trigger: Calling Remember or Supersede with a string longer than 262144 bytes: pasting a whole file/log dump, a huge JSON blob, or building memory text from unbounded user input without measuring it first.
Common situations: Scripts that pipe files or command output straight into remember (`cavemem remember < big.log`), agents summarizing transcripts into one memory instead of chunking, or a version change where a previously accepted payload grew past the cap.
Related errors
- cave_memory_too_large
- history requires memory id
- File too large to compress safely (max 500KB): {filepath}
- cachebench: nil corpus reader
- message exceeds byte limit
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/a1c99310b549ce32.
Report an issue: GitHub.