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

  1. Split the content into multiple memories under 256 KiB each, or store a summary/reference and keep the full payload elsewhere
  2. Truncate deliberately before calling Remember if only a prefix matters, after measuring len(text)
  3. 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

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


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/a1c99310b549ce32. Report an issue: GitHub.