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

  1. Inspect the wrapped error to identify the type mismatch on tag_name.
  2. Query SELECT tag_name FROM dolt_tags directly to locate NULL/malformed rows and repair or remove them.
  3. If metadata is corrupted after a version change, re-initialize or migrate the Dolt database properly.
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/6229941576ae5ecd. Report an issue: GitHub.