{"record":{"id":"9c179b16e3c277a3","repo":"JuliusBrussee/caveman","slug":"check-replacement-memory-w","errorCode":null,"errorMessage":"check replacement memory: %w","messagePattern":"check replacement memory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mem/store.go","lineNumber":230,"sourceCode":"\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,\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,","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/mem/store.go#L212-L248","documentation":"Inside the supersede transaction, the COUNT(*) check for an ID collision with the replacement memory failed at the query level. The wrapped error is the SQLite failure; the transaction rolls back with no changes.","triggerScenarios":"Thrown at mem/store.go:230 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry after transient db errors","Check mem.db health if it persists"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}