JuliusBrussee/caveman · error
read current memory
Error message
read current memory: %w
What it means
Supersede failed while reading the current row of the memory to replace from SQLite. Besides sql.ErrNoRows (reported separately as "memory %s is not current"), any other query/scan failure — locked database, I/O error, corrupted schema — is wrapped here. The store fails closed: no replacement memory is written when the current version cannot be read.
Solutions
- Check the wrapped %w cause to distinguish I/O, lock, and schema errors (errors.Unwrap / errors.As on sqlite.Error).
- Verify the database file is on local writable storage and the disk is not full.
- Ensure no other process holds a long write lock; enable busy_timeout in the SQLite DSN.
- Confirm the store file was created by this version of the schema; delete or migrate a stale store file.
Example fix
// before
new, err := store.Supersede(oldID, text)
if err != nil { log.Fatal(err) }
// after
new, err := store.Supersede(oldID, text)
if err != nil {
if strings.Contains(err.Error(), "database is locked") {
// retry with backoff or set busy_timeout in DSN
}
log.Fatalf("supersede %s: %v", oldID, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Stat(storePath); err != nil { return err } Try / catch
mem, err := store.Supersede(oldID, text)
if err != nil {
cause := errors.Unwrap(err)
log.Printf("supersede read failed: %v (cause: %v)", err, cause)
return err
} Prevention
- Keep the SQLite file on local, non-network storage
- Set busy_timeout in the DSN to tolerate concurrent writers
- Monitor disk space on the host holding the store file
- Run schema migrations before using a store from an older version
When it happens
Trigger: Calling Store.Supersede(oldID, newText) when the transaction SELECT (memorySelect + ' WHERE id = ? AND valid_until IS NULL') fails for a reason other than no rows: the database file is unreadable/corrupted, the table schema is wrong, or the connection is broken mid-query.
Common situations: SQLite file on a flaky network drive or full disk; database locked by another process holding a long write transaction; running against a store file created by an older schema version that lacks expected columns; concurrent writes causing SQLITE_BUSY.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/bad788c84bda0c06.
Report an issue: GitHub.
Appendix: source
Thrown at mem/store.go:222
}
if strings.TrimSpace(newText) == "" {
return Memory{}, fmt.Errorf("cannot supersede with empty text")
}
if err := validateMemorySize(newText); err != nil {
return Memory{}, err
}
tx, err := s.db.Begin()
if err != nil {
return Memory{}, fmt.Errorf("supersede begin: %w", err)
}
defer tx.Rollback()
var old Memory
if err := scanMemory(tx.QueryRow(memorySelect+` WHERE id = ? AND valid_until IS NULL`, oldID), &old); err != nil {
if err == sql.ErrNoRows {
return Memory{}, fmt.Errorf("memory %s is not current", oldID)
}
return Memory{}, fmt.Errorf("read current memory: %w", err)
}
if old.Text == newText {
return Memory{}, fmt.Errorf("replacement text is identical to current memory")
}
newID := memID(newText)
var exists int
if err := tx.QueryRow(`SELECT COUNT(*) FROM memories WHERE id = ?`, newID).Scan(&exists); err != nil {
return Memory{}, fmt.Errorf("check replacement memory: %w", err)
}
if exists > 0 {
return Memory{}, fmt.Errorf("replacement memory %s already exists", newID)
}
now := time.Now().UTC().Format(time.RFC3339Nano)
if _, err := tx.Exec(
`INSERT INTO memories
(id, text, created_at, valid_from, supersedes)
VALUES (?, ?, ?, ?, ?)`,
newID, newText, now, now, oldID,View on GitHub (pinned to 3ee70a1026)