{"record":{"id":"bad788c84bda0c06","repo":"JuliusBrussee/caveman","slug":"read-current-memory-w","errorCode":null,"errorMessage":"read current memory: %w","messagePattern":"read current memory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mem/store.go","lineNumber":222,"sourceCode":"\t}\n\tif strings.TrimSpace(newText) == \"\" {\n\t\treturn Memory{}, fmt.Errorf(\"cannot supersede with empty text\")\n\t}\n\tif err := validateMemorySize(newText); err != nil {\n\t\treturn Memory{}, err\n\t}\n\ttx, err := s.db.Begin()\n\tif err != nil {\n\t\treturn Memory{}, fmt.Errorf(\"supersede begin: %w\", err)\n\t}\n\tdefer tx.Rollback()\n\n\tvar old Memory\n\tif err := scanMemory(tx.QueryRow(memorySelect+` WHERE id = ? AND valid_until IS NULL`, oldID), &old); err != nil {\n\t\tif err == sql.ErrNoRows {\n\t\t\treturn Memory{}, fmt.Errorf(\"memory %s is not current\", oldID)\n\t\t}\n\t\treturn Memory{}, fmt.Errorf(\"read current memory: %w\", err)\n\t}\n\tif old.Text == newText {\n\t\treturn Memory{}, fmt.Errorf(\"replacement text is identical to current memory\")\n\t}\n\tnewID := memID(newText)\n\tvar exists int\n\tif err := tx.QueryRow(`SELECT COUNT(*) FROM memories WHERE id = ?`, newID).Scan(&exists); err != nil {\n\t\treturn Memory{}, fmt.Errorf(\"check replacement memory: %w\", err)\n\t}\n\tif exists > 0 {\n\t\treturn Memory{}, fmt.Errorf(\"replacement memory %s already exists\", newID)\n\t}\n\tnow := time.Now().UTC().Format(time.RFC3339Nano)\n\tif _, err := tx.Exec(\n\t\t`INSERT INTO memories\n\t\t   (id, text, created_at, valid_from, supersedes)\n\t\t VALUES (?, ?, ?, ?, ?)`,\n\t\tnewID, newText, now, now, oldID,","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/mem/store.go#L204-L240","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nnew, err := store.Supersede(oldID, text)\nif err != nil { log.Fatal(err) }\n// after\nnew, err := store.Supersede(oldID, text)\nif err != nil {\n\tif strings.Contains(err.Error(), \"database is locked\") {\n\t\t// retry with backoff or set busy_timeout in DSN\n\t}\n\tlog.Fatalf(\"supersede %s: %v\", oldID, err)\n}","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(storePath); err != nil { return err }","typeGuard":null,"tryCatchPattern":"mem, err := store.Supersede(oldID, text)\nif err != nil {\n\tcause := errors.Unwrap(err)\n\tlog.Printf(\"supersede read failed: %v (cause: %v)\", err, cause)\n\treturn err\n}","preventionTips":["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"],"tags":["database","sqlite","persistence"],"backgroundTag":"database-query-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}