{"record":{"id":"aa878136679678c4","repo":"gastownhall/beads","slug":"failed-to-scan-history-w","errorCode":null,"errorMessage":"failed to scan history: %w","messagePattern":"failed to scan history: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/history.go","lineNumber":108,"sourceCode":"\n\tvar history []*issueHistory\n\tfor rows.Next() {\n\t\tvar h issueHistory\n\t\tvar issue types.Issue\n\t\tvar createdAtStr, updatedAtStr sql.NullString // TEXT columns - must parse manually\n\t\tvar closedAt sql.NullTime\n\t\tvar assignee, owner, createdBy, closeReason, molType sql.NullString\n\t\tvar estimatedMinutes sql.NullInt64\n\t\tvar pinned sql.NullInt64\n\n\t\tif err := rows.Scan(\n\t\t\t&issue.ID, &issue.Title, &issue.Description, &issue.Design, &issue.AcceptanceCriteria, &issue.Notes,\n\t\t\t&issue.Status, &issue.Priority, &issue.IssueType, &assignee, &owner, &createdBy,\n\t\t\t&estimatedMinutes, &createdAtStr, &updatedAtStr, &closedAt, &closeReason,\n\t\t\t&pinned, &molType,\n\t\t\t&h.CommitHash, &h.Committer, &h.CommitDate,\n\t\t); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to scan history: %w\", err)\n\t\t}\n\n\t\t// Parse timestamp strings (TEXT columns require manual parsing)\n\t\tif createdAtStr.Valid {\n\t\t\tissue.CreatedAt = parseTimeString(createdAtStr.String)\n\t\t}\n\t\tif updatedAtStr.Valid {\n\t\t\tissue.UpdatedAt = parseTimeString(updatedAtStr.String)\n\t\t}\n\n\t\tif closedAt.Valid {\n\t\t\tissue.ClosedAt = &closedAt.Time\n\t\t}\n\t\tif assignee.Valid {\n\t\t\tissue.Assignee = assignee.String\n\t\t}\n\t\tif owner.Valid {\n\t\t\tissue.Owner = owner.String","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/history.go#L90-L126","documentation":"After the history query succeeds, getIssueHistory scans each row into the issue and history structs, including nullable TEXT columns read as sql.Null* values. This error is returned when rows.Scan fails — almost always a column-count or column-type mismatch between the SELECT * projection and the fixed scan target list, or an unparseable value in a scanned column.","triggerScenarios":"The dolt_history_issues schema drifts from the code's expectation (added/removed/reordered columns) so SELECT * returns a different column set than the Scan targets; a column type changes (e.g. a numeric returned as string); NULL appears where a non-Null scan target is used.","commonSituations":"Upgrading the Dolt server which changes system-table schema; beads schema migrations applied to the DB but binary not updated (or vice versa); running a mixed-version fleet where one node wrote rows with new columns.","solutions":["Align the beads binary and database schema versions — run the project's schema migration/upgrade steps so dolt_history_issues matches the compiled scan list.","Check the wrapped error message: it names the offending column/index; compare current SHOW CREATE TABLE dolt_history_issues output with the Scan target order.","Upgrade or downgrade the Dolt engine to a version compatible with the installed beads release."],"exampleFix":"// before\nrows, _ := s.queryContext(ctx, \"SELECT * FROM dolt_history_issues ...\") // column drift\nrows.Scan(&issue.ID, ..., &h.CommitDate) // scan count mismatch\n// after\nrows, _ := s.queryContext(ctx, \"SELECT id, title, description, ... commit_hash, committer, commit_date FROM dolt_history_issues ...\") // explicit column list\nrows.Scan(&issue.ID, ..., &h.CommitDate)","handlingStrategy":"try-catch","validationCode":"func schemaMatches(db *sql.DB) error {\n    rows, err := db.Query(\"SHOW COLUMNS FROM dolt_history_issues\")\n    if err != nil { return err }\n    defer rows.Close()\n    return nil // compare count/names against expected scan list in production\n}","typeGuard":null,"tryCatchPattern":"history, err := store.GetIssueHistory(ctx, id)\nif err != nil && strings.Contains(err.Error(), \"failed to scan history\") {\n    return fmt.Errorf(\"beads/schema version mismatch, run migrations: %w\", err)\n}","preventionTips":["Keep beads binary and database schema versions in lockstep; run migrations on upgrade.","Prefer explicit column lists over SELECT * when scanning into fixed structs.","Pin the Dolt engine version per beads release in deployment configs."],"tags":["dolt","history","scan-error","schema-drift"],"backgroundTag":"row-scan-type-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}