gastownhall/beads · error

failed to scan stale issue id: %w

Error message

failed to scan stale issue id: %w

What it means

GetStaleIssuesInTx scans a single string (the issue id) from each row of the stale-issues SELECT; this error wraps a rows.Scan failure. With a literal single-column 'SELECT id' this almost always means the row value was NULL (sql.Scan into string fails) or the driver returned an unexpected column type.

Source

Thrown at internal/storage/issueops/stale.go:77

	if filter.Limit > 0 {
		query += fmt.Sprintf(" LIMIT %d", filter.Limit)
	}

	rows, err := tx.QueryContext(ctx, query, args...)
	if err != nil {
		return nil, fmt.Errorf("failed to get stale issues: %w", err)
	}

	// Collect IDs first, then batch-fetch full issues.
	// Close rows explicitly before the nested fetch — MySQL/Dolt drivers
	// can't handle multiple active result sets on one connection.
	var ids []string
	for rows.Next() {
		var id string
		if err := rows.Scan(&id); err != nil {
			rows.Close()
			return nil, fmt.Errorf("failed to scan stale issue id: %w", err)
		}
		ids = append(ids, id)
	}
	if err := rows.Err(); err != nil {
		rows.Close()
		return nil, fmt.Errorf("stale issues rows: %w", err)
	}
	rows.Close()

	if len(ids) == 0 {
		return nil, nil
	}

	// GetIssuesByIDsInTx returns issues in arbitrary order (WHERE IN),
	// so re-order to preserve the updated_at ASC ordering from the query.
	issues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)
	if err != nil {
		return nil, err

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the issues table for rows with NULL ids (SELECT COUNT(*) FROM issues WHERE id IS NULL) and repair or delete them.
  2. If the schema was customized, restore the standard schema so id is a non-null primary key.
  3. Check the driver version (Dolt/MySQL) matches what the library expects; upgrade or pin it.
  4. If the error persists, capture the wrapped error text to confirm whether it is a NULL-conversion error (sql: Scan error ... converting NULL to string).

Example fix

// before
// NULL ids present in corrupted table
// after
DELETE FROM issues WHERE id IS NULL; -- repair corrupted rows
Defensive patterns

Strategy: validation

Validate before calling

// detect NULL ids in the issues table before scanning
var nulls int
_ = tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM issues WHERE id IS NULL`).Scan(&nulls)
if nulls > 0 { return fmt.Errorf("%d issues rows have NULL ids; repair database", nulls) }

Try / catch

ids, err := issueops.GetStaleIssuesInTx(ctx, tx, filter)
if err != nil && strings.Contains(err.Error(), "converting NULL to string") {
    return fmt.Errorf("corrupt issues table (NULL id); run repair: %w", err)
}

Prevention

When it happens

Trigger: A row in issues has a NULL id column (corrupted data or an aliased/modified query), or the driver returns an id in a type database/sql cannot convert into a Go string.

Common situations: A corrupted or manually edited Dolt/MySQL database where issues.id is NULL; running against a schema variant where id is not the first/only returned column; driver version mismatches altering scan behavior.

Related errors


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