{"record":{"id":"d4b59563ff47e87b","repo":"JuliusBrussee/caveman","slug":"read-applied-fix-id-w","errorCode":null,"errorMessage":"read applied fix id: %w","messagePattern":"read applied fix id: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/store/learn_outcomes.go","lineNumber":114,"sourceCode":"\t// `caveman learn applied` time is immediately after the approved edit. This\n\t// is the provenance anchor: a later scan re-hashes the same path and can\n\t// state whether the change we proposed is still the change that is there.\n\ttarget := fingerprintFixTarget(*sink)\n\ttargetJSON := \"\"\n\tif target != nil {\n\t\tif encoded, encodeErr := json.Marshal(target); encodeErr == nil {\n\t\t\ttargetJSON = string(encoded)\n\t\t}\n\t}\n\tresult, err := s.db.Exec(`INSERT INTO applied_fixes\n\t\t(sink_id, practice_id, fix_kind, applied_at, before_tokens_per_turn, before_evidence_json, note, target_json)\n\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?)`, sink.SinkID, sink.PracticeID, fixKind, appliedAt, sink.TokensPerTurn, string(evidence), note, targetJSON)\n\tif err != nil {\n\t\treturn AppliedFixRecord{}, fmt.Errorf(\"record applied fix: %w\", err)\n\t}\n\tid, err := result.LastInsertId()\n\tif err != nil {\n\t\treturn AppliedFixRecord{}, fmt.Errorf(\"read applied fix id: %w\", err)\n\t}\n\treturn AppliedFixRecord{\n\t\tRecorded: true, ID: id, SinkID: sink.SinkID, PracticeID: sink.PracticeID,\n\t\tFixKind: fixKind, AppliedAt: appliedAt, BeforeTokensPerTurn: sink.TokensPerTurn,\n\t\tBeforeEvidence: beforeEvidence, BeforeSource: beforeSource, Note: note,\n\t\tTarget: target,\n\t}, nil\n}\n\nfunc beforeSinkForAppliedFix(plan LearnPlan, sinkID string, live *Sink, fallbackCutoff time.Time) (*Sink, string) {\n\tcutoff := fallbackCutoff\n\tif parsed, err := time.Parse(time.RFC3339Nano, plan.computedAt); err == nil {\n\t\tcutoff = parsed\n\t}\n\tif snapshot := newestLearnSnapshotSink(sinkID, cutoff); snapshot != nil {\n\t\treturn snapshot, \"report_snapshot\"\n\t}\n\tif live != nil {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/proxy/internal/store/learn_outcomes.go#L96-L132","documentation":"After a successful INSERT, RecordAppliedFix calls result.LastInsertId() to get the new row's ID. If the driver cannot report it the error is wrapped as \"read applied fix id\". SQLite via mattn/go-sqlite3 or modernc supports this, so failure indicates a driver/connection-level problem.","triggerScenarios":"LastInsertId() returning an error on the just-executed INSERT result — typically with a driver/pool that doesn't support LastInsertId (e.g. some proxies or non-SQLite drivers behind database/sql).","commonSituations":"Swapping the SQLite driver for one lacking LastInsertId support; using the result after the connection was reset.","solutions":["Verify the registered driver supports LastInsertId for INSERT (use mattn/go-sqlite3 or modernc.org/sqlite)","Read the wrapped %w error to confirm the driver-level cause","If the driver can't provide it, query last_insert_rowid() in the same connection instead"],"exampleFix":"// before\nid, err := result.LastInsertId()\n// after\nvar id int64\nerr = s.db.QueryRow(\"SELECT last_insert_rowid()\").Scan(&id)","handlingStrategy":"try-catch","validationCode":"// ensure driver supports LastInsertId: use modernc.org/sqlite or github.com/mattn/go-sqlite3","typeGuard":null,"tryCatchPattern":"if _, err := store.RecordAppliedFix(ctx, sink, kind, note); err != nil { if strings.Contains(err.Error(), \"read applied fix id\") { log.Error(\"driver lacks LastInsertId support; check sqlite driver\") } }","preventionTips":["Pin a known-good SQLite driver that implements LastInsertId","Don't interpose generic SQL drivers/proxies over the store DB","Add an integration test that records a fix and asserts Recorded==true with a positive ID"],"tags":["sqlite","database","driver"],"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"}