{"record":{"id":"ec87b1d2a1ef503d","repo":"gastownhall/beads","slug":"errscan","errorCode":"ErrScan","errorMessage":"scan error","messagePattern":"scan error","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/errors.go","lineNumber":28,"sourceCode":"\n\tmysql \"github.com/go-sql-driver/mysql\"\n\n\t\"github.com/steveyegge/beads/internal/storage\"\n\t\"github.com/steveyegge/beads/internal/storage/dberrors\"\n)\n\n// Sentinel errors for the dolt storage layer.\n// These complement the storage-level sentinels (storage.ErrNotFound, etc.)\n// with dolt-specific error types.\nvar (\n\t// ErrTransaction indicates a transaction begin/commit/rollback failure.\n\tErrTransaction = errors.New(\"transaction error\")\n\n\t// ErrQuery indicates a database query failure.\n\tErrQuery = errors.New(\"query error\")\n\n\t// ErrScan indicates a failure scanning database rows into Go values.\n\tErrScan = errors.New(\"scan error\")\n\n\t// ErrExec indicates a database exec (INSERT/UPDATE/DELETE) failure.\n\tErrExec = errors.New(\"exec error\")\n\n\t// ErrDanglingReference indicates that the pre-push integrity check detected\n\t// missing chunks in the local Dolt noms store. The push was aborted to\n\t// prevent propagating the corruption to the remote. Run bd dolt verify\n\t// to diagnose and recover.\n\tErrDanglingReference = errors.New(\"dangling chunk reference\")\n\n\t// ErrFSCKTimeout indicates that the pre-push integrity check (dolt fsck) did\n\t// not complete within the configured timeout. The push was aborted without\n\t// verifying chunk integrity — the store is not necessarily corrupt. Large\n\t// stores can be shrunk with `dolt gc` (or `CALL DOLT_GC()` on a running\n\t// sql-server); the timeout can be raised via the BEADS_FSCK_TIMEOUT\n\t// environment variable.\n\tErrFSCKTimeout = errors.New(\"pre-push integrity check timed out\")\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/errors.go#L10-L46","documentation":"ErrScan is the dolt storage layer's sentinel for failures converting database rows into Go values — rows.Scan failing because column types or count don't match the destination (e.g. NULL into a non-nullable field, column added/renamed by a schema change). wrapScanError embeds it in the chain for errors.Is classification.","triggerScenarios":"Any dolt-backed read where rows.Scan fails after a successful query: schema drift between the running code and the database (a column added, removed, or type-changed), unexpected NULL in a column scanned into a non-pointer type, or a column order/count mismatch in hand-written SELECTs.","commonSituations":"Rolling back the bd binary to an older version against a newer migrated database; a partially applied or failed migration; manually editing the schema; database written by a newer bd version and read by an older one.","solutions":["Compare your bd binary version with the database schema version (bd doctor) — upgrade or migrate so they match","Read the wrapped error for the exact column mismatch: errors.Is(err, dolt.ErrScan) then unwrap","If caused by version rollback, re-upgrade the binary or restore a matching backup (bd backup restore)","Fix the NULL source or change the scan destination to a pointer/sql.Null* type if you own the query"],"exampleFix":"// before\nvar assignee string\nif err := row.Scan(&id, &assignee); err != nil { return err } // fails on NULL assignee\n// after\nvar assignee sql.NullString\nif err := row.Scan(&id, &assignee); err != nil {\n    if errors.Is(err, dolt.ErrScan) { /* schema drift: check bd doctor */ }\n    return err\n}\na := assignee.String // empty when NULL","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isScanError(err error) bool {\n    return errors.Is(err, dolt.ErrScan)\n}","tryCatchPattern":"if err := store.List(ctx); err != nil {\n    if errors.Is(err, dolt.ErrScan) {\n        return fmt.Errorf(\"schema mismatch between binary and database; run bd doctor / re-migrate: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep the bd binary and database schema versions in sync — never roll back the binary across migrations","Run bd doctor after version changes to detect schema drift early","Scan nullable columns into sql.Null* types or pointers","Let migrations own all schema changes; avoid hand-editing the database","Back up before upgrades so a bad migration can be restored (bd backup restore)"],"tags":["go","database","scan","schema-drift","dolt","sentinel-error"],"backgroundTag":"row-scan-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}