{"record":{"id":"f9695f7424b5630b","repo":"gastownhall/beads","slug":"scan-remote-w","errorCode":null,"errorMessage":"scan remote: %w","messagePattern":"scan remote: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/remotes.go","lineNumber":22,"sourceCode":"\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/steveyegge/beads/internal/storage\"\n)\n\n// ListRemotes returns all configured Dolt remotes (name and URL).\nfunc ListRemotes(ctx context.Context, db DBConn) ([]storage.RemoteInfo, error) {\n\trows, err := db.QueryContext(ctx, \"SELECT name, url FROM dolt_remotes\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"list remotes: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tvar remotes []storage.RemoteInfo\n\tfor rows.Next() {\n\t\tvar r storage.RemoteInfo\n\t\tif err := rows.Scan(&r.Name, &r.URL); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"scan remote: %w\", err)\n\t\t}\n\t\tremotes = append(remotes, r)\n\t}\n\treturn remotes, rows.Err()\n}\n\n// RemoveRemote removes a configured Dolt remote.\nfunc RemoveRemote(ctx context.Context, db DBConn, name string) error {\n\tif _, err := db.ExecContext(ctx, \"CALL DOLT_REMOTE('remove', ?)\", name); err != nil {\n\t\treturn fmt.Errorf(\"remove remote %s: %w\", name, err)\n\t}\n\treturn nil\n}\n\n// Fetch fetches refs from a remote without merging.\n//\n// If user is non-empty, authenticates with that user — DOLT_REMOTE_PASSWORD\n// must be set in the in-process Dolt server's environment.","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/remotes.go#L4-L40","documentation":"ListRemotes scans each row of the dolt_remotes result into a storage.RemoteInfo via rows.Scan(&r.Name, &r.URL). This error is thrown when a row's columns cannot be converted into the two destination fields — most often a column-count or type mismatch between the result set and the scan targets. It identifies the failure as occurring mid-iteration, not at query time.","triggerScenarios":"Calling ListRemotes on a Dolt version whose dolt_remotes table has different column count/order than (name, url), or NULL/non-string values that database/sql cannot scan into *string fields.","commonSituations":"Dolt engine upgrade changed the dolt_remotes schema; connecting to a different storage engine where the query returns extra columns; driver returning typed values incompatible with string destinations.","solutions":["Run SELECT name, url FROM dolt_remotes manually and check the column count/types","Upgrade or align the Dolt engine version with what beads expects","Scan into sql.RawBytes/sql.NullString if values can be NULL, then convert","Check for driver-specific type mapping issues in the installed dolt driver"],"exampleFix":"// before\nif err := rows.Scan(&r.Name, &r.URL); err != nil {\n\treturn nil, fmt.Errorf(\"scan remote: %w\", err)\n}\n// after\nvar name, url sql.NullString\nif err := rows.Scan(&name, &url); err != nil {\n\treturn nil, fmt.Errorf(\"scan remote: %w\", err)\n}\nr.Name, r.URL = name.String, url.String","handlingStrategy":"validation","validationCode":"// Probe the dolt_remotes schema before scanning\nrows, err := db.QueryContext(ctx, \"SELECT name, url FROM dolt_remotes LIMIT 1\")\nif err != nil {\n\treturn err\n}\nrows.Close()","typeGuard":"func isScanMismatch(err error) bool {\n\tvar convErr *sql.ConvertError\n\treturn errors.As(err, &convErr) || strings.Contains(err.Error(), \"expected \")\n}","tryCatchPattern":"remotes, err := versioncontrolops.ListRemotes(ctx, db)\nif err != nil {\n\tif isScanMismatch(err) {\n\t\tlog.Warn(\"dolt_remotes schema mismatch; upgrade Dolt engine\")\n\t}\n\treturn err\n}","preventionTips":["Keep the Dolt engine version aligned with the version beads was built against","After engine upgrades, smoke-test SELECT name, url FROM dolt_remotes","Treat unexpected column counts as an upgrade signal, not a data problem","Avoid NULLs in dolt_remotes values (they are engine-managed, but verify after manual edits)"],"tags":["dolt","sql-scan","schema-mismatch","remotes"],"backgroundTag":"sql-scan-error","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}