{"record":{"id":"2bc742111a68dfea","repo":"gastownhall/beads","slug":"scan-remote-tracking-ref-w","errorCode":null,"errorMessage":"scan remote-tracking ref: %w","messagePattern":"scan remote-tracking ref: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/remoterefs.go","lineNumber":21,"sourceCode":"import (\n\t\"context\"\n\t\"fmt\"\n)\n\n// ListRemoteRefs returns the names of all cached remote-tracking refs\n// (e.g. \"remotes/origin/main\"), sorted by name.\nfunc ListRemoteRefs(ctx context.Context, db DBConn) ([]string, error) {\n\trows, err := db.QueryContext(ctx, \"SELECT name FROM dolt_remote_branches ORDER BY name\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"list remote-tracking refs: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tvar refs []string\n\tfor rows.Next() {\n\t\tvar name string\n\t\tif err := rows.Scan(&name); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"scan remote-tracking ref: %w\", err)\n\t\t}\n\t\trefs = append(refs, name)\n\t}\n\treturn refs, rows.Err()\n}\n\n// PruneRemoteRefs deletes every cached remote-tracking ref and returns the\n// names deleted. After a history squash (Flatten/Compact) these refs still\n// anchor the pre-squash commit chain, so DOLT_GC treats the entire old history\n// as reachable and reclaims nothing (bd-agctw). Pruning is safe on a squashed\n// workspace: the refs are local caches only — nothing is deleted on the remote\n// itself — and the next push or fetch re-creates them at the new tip.\n//\n// On error, the returned slice holds the refs deleted before the failure.\nfunc PruneRemoteRefs(ctx context.Context, db DBConn) ([]string, error) {\n\trefs, err := ListRemoteRefs(ctx, db)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/remoterefs.go#L3-L39","documentation":"ListRemoteRefs iterates rows from dolt_remote_branches and scans each row's name column into a string. This error wraps a rows.Scan failure — the driver could not convert the row value into a *string, or the row is in an unexpected shape. It is thrown so the listing step reports per-row data problems distinctly from query errors.","triggerScenarios":"A row in dolt_remote_branches has a NULL or non-string name value that cannot be scanned into a Go string; the driver returns rows in an unexpected column layout after a Dolt engine change.","commonSituations":"Corrupted or partially-migrated Dolt metadata after an upgrade/downgrade; a Dolt version where dolt_remote_branches exposes different column types; NULL ref names left by an interrupted operation.","solutions":["Inspect the wrapped error to identify the offending column/value type mismatch.","Run SELECT name FROM dolt_remote_branches manually to find rows with NULL or malformed names and repair or remove them.","Upgrade or re-initialize the Dolt database if metadata was corrupted by a version change (e.g. after a failed migration).","Check rows.Err() after iteration to ensure the row set itself is intact."],"exampleFix":"// before\nif err := rows.Scan(&name); err != nil {\n    return nil, fmt.Errorf(\"scan remote-tracking ref: %w\", err)\n}\n// after: tolerate NULLs with sql.NullString\nvar name sql.NullString\nif err := rows.Scan(&name); err != nil {\n    return nil, fmt.Errorf(\"scan remote-tracking ref: %w\", err)\n}\nif !name.Valid { continue }","handlingStrategy":"validation","validationCode":"rows, err := db.QueryContext(ctx, \"SELECT name FROM dolt_remote_branches WHERE name IS NOT NULL ORDER BY name\")\nif err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"refs, err := versioncontrolops.ListRemoteRefs(ctx, db)\nvar scanErr *sql.ScanError\nif err != nil && errors.As(err, &scanErr) {\n    log.Printf(\"malformed ref row, falling back to raw query: %v\", err)\n    refs, err = queryRefsManually(ctx, db)\n}","preventionTips":["Filter NULL names in the query or use sql.NullString when reading system tables.","Pin and test against your Dolt engine version; re-check column types after upgrades.","Check rows.Err() after iterating result sets.","Repair corrupted metadata promptly instead of letting it accumulate."],"tags":["dolt","sql","row-scan"],"backgroundTag":"sql-row-scan-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}