gastownhall/beads · error
scan tag: %w
Error message
scan tag: %w
What it means
ListTags scans each row from dolt_tags into a string via rows.Scan. This error wraps a per-row scan failure — the driver could not convert a tag_name value (NULL or non-string type) into a Go string, or the row shape is unexpected. It distinguishes data-shape problems in the tag table from the query-level failure reported by the list-tags error.
Source
Thrown at internal/storage/versioncontrolops/remoterefs.go:65
}
return pruned, nil
}
// ListTags returns the names of all Dolt tags, sorted by name. Tags anchor
// history the same way remote-tracking refs do, but they are user-created, so
// callers should surface them rather than delete them.
func ListTags(ctx context.Context, db DBConn) ([]string, error) {
rows, err := db.QueryContext(ctx, "SELECT tag_name FROM dolt_tags ORDER BY tag_name")
if err != nil {
return nil, fmt.Errorf("list tags: %w", err)
}
defer rows.Close()
var tags []string
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
return nil, fmt.Errorf("scan tag: %w", err)
}
tags = append(tags, name)
}
return tags, rows.Err()
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped error to identify the type mismatch on tag_name.
- Query SELECT tag_name FROM dolt_tags directly to locate NULL/malformed rows and repair or remove them.
- If metadata is corrupted after a version change, re-initialize or migrate the Dolt database properly.
- Verify rows.Err() after iteration to catch iteration-level failures separately.
Example fix
// before
var name string
if err := rows.Scan(&name); err != nil {
return nil, fmt.Errorf("scan tag: %w", err)
}
// after: tolerate NULLs with sql.NullString
var name sql.NullString
if err := rows.Scan(&name); err != nil {
return nil, fmt.Errorf("scan tag: %w", err)
}
if !name.Valid { continue } Defensive patterns
Strategy: validation
Validate before calling
rows, err := db.QueryContext(ctx, "SELECT tag_name FROM dolt_tags WHERE tag_name IS NOT NULL ORDER BY tag_name")
if err != nil {
return err
} Try / catch
tags, err := versioncontrolops.ListTags(ctx, db)
var scanErr *sql.ScanError
if err != nil && errors.As(err, &scanErr) {
log.Printf("malformed tag row: %v", err)
tags, err = queryTagsManually(ctx, db) // fallback raw query
} Prevention
- Use sql.NullString or filter NULLs when reading dolt_tags.
- Check rows.Err() after iteration to catch iteration-level failures.
- Re-validate tag metadata after Dolt version upgrades/migrations.
- Never interrupt DOLT_TAG operations; abrupt shutdowns can leave malformed rows.
When it happens
Trigger: A dolt_tags row has a NULL or non-string tag_name that cannot scan into *string; the Dolt engine returns dolt_tags with altered column types after a version change.
Common situations: Corrupted tag metadata after a failed migration or abrupt shutdown; Dolt upgrade/downgrade changing dolt_tags column types; NULL tag names from an interrupted DOLT_TAG operation.
Related errors
- scan remote-tracking ref: %w
- failed to open server connection: %w
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6229941576ae5ecd.
Report an issue: GitHub.