{"record":{"id":"afcab6370a605eff","repo":"JuliusBrussee/caveman","slug":"insert-replacement-memory-w","errorCode":null,"errorMessage":"insert replacement memory: %w","messagePattern":"insert replacement memory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mem/store.go","lineNumber":242,"sourceCode":"\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,\n\t); err != nil {\n\t\treturn Memory{}, fmt.Errorf(\"insert replacement memory: %w\", err)\n\t}\n\tres, err := tx.Exec(\n\t\t`UPDATE memories\n\t\t    SET valid_until = ?, superseded_by = ?\n\t\t  WHERE id = ? AND valid_until IS NULL`,\n\t\tnow, newID, oldID,\n\t)\n\tif err != nil {\n\t\treturn Memory{}, fmt.Errorf(\"expire old memory: %w\", err)\n\t}\n\tif n, _ := res.RowsAffected(); n != 1 {\n\t\treturn Memory{}, fmt.Errorf(\"memory %s changed during supersede\", oldID)\n\t}\n\tif err := tx.Commit(); err != nil {\n\t\treturn Memory{}, fmt.Errorf(\"supersede commit: %w\", err)\n\t}\n\treturn Memory{\n\t\tID:         newID,","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/mem/store.go#L224-L260","documentation":"Supersede failed while inserting the replacement memory row into the memories table. The insert runs inside the supersede transaction, so any failure (constraint violation, lock, I/O error) aborts the whole operation and no lineage change is persisted.","triggerScenarios":"Calling Store.Supersede(oldID, newText) when the INSERT of the new (id, text, created_at, valid_from, supersedes) row fails: disk full, database locked, constraint violation, or corrupted schema.","commonSituations":"Disk quota exceeded while writing the SQLite file; concurrent writers causing SQLITE_BUSY; database file opened read-only; schema drift between library versions.","solutions":["Check the wrapped cause (errors.Unwrap / errors.As on the driver error).","Free disk space / verify write permissions on the store file.","Add busy_timeout and retry on lock errors.","Confirm the store file matches the current schema version."],"exampleFix":"// before\nnew, err := store.Supersede(oldID, text)\nif err != nil { return err }\n// after\nnew, err := store.Supersede(oldID, text)\nif err != nil {\n\treturn fmt.Errorf(\"supersede %s: %w\", oldID, err) // surface wrapped cause for diagnosis\n}","handlingStrategy":"try-catch","validationCode":"if err := checkDiskSpace(storeDir); err != nil { return err }","typeGuard":null,"tryCatchPattern":"_, err := store.Supersede(oldID, text)\nif err != nil {\n\tlog.Printf(\"insert replacement failed: %v\", errors.Unwrap(err))\n\treturn err\n}","preventionTips":["Monitor free disk space for the store directory","Avoid read-only mounts for the database file","Set busy_timeout and serialize writers","Keep the store schema aligned with the library version"],"tags":["database","sqlite","write-failure"],"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"}