{"record":{"id":"32fe546d0940919f","repo":"gastownhall/beads","slug":"failed-to-get-previous-external-ref-w","errorCode":null,"errorMessage":"failed to get previous external_ref: %w","messagePattern":"failed to get previous external_ref: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/history.go","lineNumber":128,"sourceCode":"//\n// The subquery wrapper avoids Dolt's max1Row optimization on PK lookup, for\n// the same reason described on HistoryInTx above.\nfunc PreviousExternalRefInTx(ctx context.Context, tx *sql.Tx, issueID string, asOf time.Time) (string, bool, error) {\n\tvar previousRef sql.NullString\n\terr := tx.QueryRowContext(ctx, `\n\t\tSELECT external_ref\n\t\tFROM (\n\t\t\tSELECT id, external_ref, commit_date FROM dolt_history_issues\n\t\t) h\n\t\tWHERE h.id = ? AND h.commit_date <= ?\n\t\tORDER BY h.commit_date DESC\n\t\tLIMIT 1\n\t`, issueID, asOf.UTC()).Scan(&previousRef)\n\tif err == sql.ErrNoRows {\n\t\treturn \"\", false, nil\n\t}\n\tif err != nil {\n\t\treturn \"\", false, fmt.Errorf(\"failed to get previous external_ref: %w\", err)\n\t}\n\treturn previousRef.String, true, nil\n}\n","sourceCodeStart":110,"sourceCodeEnd":132,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/history.go#L110-L132","documentation":"PreviousExternalRefInTx wraps an unexpected database error from querying the most recent external_ref before a given timestamp. sql.ErrNoRows is handled separately and is NOT an error (returns \"\", false, nil); only genuine driver/query failures reach this wrapper.","triggerScenarios":"The query `SELECT external_ref ... ORDER BY ... LIMIT 1` fails due to table not existing, connection loss, lock timeout, or malformed timestamp argument conversion.","commonSituations":"Database unavailable mid-transaction; schema drift removing the external_ref column; Dolt backend hiccup or lock contention under concurrent writers.","solutions":["Inspect the wrapped driver error to identify the root cause","Verify the issues table and external_ref column exist in the schema","Check database connectivity and transaction state","Retry the transaction; transient Dolt/SQL errors often resolve on retry"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"var n int\nerr := db.QueryRow(\"SELECT COUNT(*) FROM information_schema.columns WHERE table_name='issues' AND column_name='external_ref'\").Scan(&n)\nif n == 0 { /* run migration */ }","typeGuard":"null","tryCatchPattern":"ref, ok, err := issueops.PreviousExternalRefInTx(ctx, tx, issueID, asOf)\nif err != nil {\n  if isTransient(err) { return retry(...) }\n  return fmt.Errorf(\"previous external_ref lookup failed: %w\", err)\n}","preventionTips":["Treat (\"\", false, nil) as a normal result — it means no prior ref, not an error","Check DB health before long transactions","Keep the issues table schema in sync with the code version"],"tags":["sql","query","external-ref","storage"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}