{"record":{"id":"a9b62aa98ea10db7","repo":"JuliusBrussee/caveman","slug":"repair-forgotten-successor-w","errorCode":null,"errorMessage":"repair forgotten successor: %w","messagePattern":"repair forgotten successor: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mem/store.go","lineNumber":353,"sourceCode":"\t\tif err == sql.ErrNoRows {\n\t\t\treturn false, nil\n\t\t}\n\t\treturn false, fmt.Errorf(\"read forgotten memory: %w\", err)\n\t}\n\tif supersedes.Valid {\n\t\tif _, err := tx.Exec(\n\t\t\t`UPDATE memories SET superseded_by = ? WHERE id = ?`,\n\t\t\tnullableLineageID(supersededBy), supersedes.String,\n\t\t); err != nil {\n\t\t\treturn false, fmt.Errorf(\"repair forgotten predecessor: %w\", err)\n\t\t}\n\t}\n\tif supersededBy.Valid {\n\t\tif _, err := tx.Exec(\n\t\t\t`UPDATE memories SET supersedes = ? WHERE id = ?`,\n\t\t\tnullableLineageID(supersedes), supersededBy.String,\n\t\t); err != nil {\n\t\t\treturn false, fmt.Errorf(\"repair forgotten successor: %w\", err)\n\t\t}\n\t}\n\tif _, err := tx.Exec(`DELETE FROM memories WHERE id = ?`, id); err != nil {\n\t\treturn false, fmt.Errorf(\"forget: %w\", err)\n\t}\n\tif err := tx.Commit(); err != nil {\n\t\treturn false, fmt.Errorf(\"forget commit: %w\", err)\n\t}\n\treturn true, nil\n}\n\nfunc nullableLineageID(value sql.NullString) any {\n\tif value.Valid {\n\t\treturn value.String\n\t}\n\treturn nil\n}\n","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/mem/store.go#L335-L371","documentation":"When the forgotten memory has a successor (superseded_by is set), Forget() rewrites the successor's supersedes pointer (usually to NULL) so the chain skips the deleted record. A failure of this UPDATE rolls back the transaction and is wrapped as this error. As with the predecessor repair, this is a SQLite write failure, not a lineage-logic error.","triggerScenarios":"Calling Forget(id) on a superseded (older) version while the database is read-only or full, the write lock is held by another process, or the affected pages are corrupted.","commonSituations":"Forgetting history entries from a DB opened on a read-only volume, a full disk during cleanup of old versions, two processes deleting simultaneously, or corrupted WAL sidecar files blocking writes.","solutions":["Verify write access to the DB and its -wal/-shm files; fix ownership/permissions and retry.","Free disk space if `df -h` shows the volume full, then retry the forget.","Check `lsof <db>` for other writers; stop them or add a busy timeout (`?_busy_timeout=5000`) to ride out short locks.","If corruption is suspected (`PRAGMA integrity_check` fails), restore from a clean backup; stop writers before copying DB files."],"exampleFix":"# before: cleanup fails on a full disk\n$ cavemem forget old-version-id\n# forget: repair forgotten successor: database or disk is full\n# after: free space, then retry\n$ df -h /data && cavemem forget old-version-id","handlingStrategy":"retry","validationCode":"// Go: verify free disk space before write-heavy store operations\nconst minFreeBytes = 10 << 20\nfunc hasDiskSpace(path string) bool {\n\tvar st syscall.Statfs_t\n\tif syscall.Statfs(filepath.Dir(path), &st) != nil { return false }\n\treturn int64(st.Bavail)*int64(st.Bsize) > minFreeBytes\n}","typeGuard":"null","tryCatchPattern":"ok, err := store.Forget(id)\nif err != nil && strings.Contains(err.Error(), \"repair forgotten successor\") {\n\t// fix storage condition (space/permissions/lock) then retry; transaction rolled back cleanly\n\treturn retryForget(store, id, 3)\n}","preventionTips":["Monitor free space on the DB volume; full disks are the top cause of mid-transaction write failures.","Keep only one writer process per database, or enable WAL mode with a busy timeout.","Don't chmod the DB read-only while a long-lived server holds it open.","Run `PRAGMA integrity_check;` after any crash; corrupted pages cause subsequent UPDATE failures."],"tags":["sqlite","write-failed","transaction","lineage"],"backgroundTag":"database-write-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"}