gastownhall/beads · error
backfill custom_statuses: %w
Error message
backfill custom_statuses: %w
What it means
Wrapper from ensureBackfilledCustomStatusesCustomTypes when backfillCustomStatuses — seeding the custom_statuses table from configured custom statuses — fails. The raw driver error is wrapped with %w so the root cause (missing table, bad connection, permissions) stays intact. Raised during MigrateUp after the custom_types backfill step.
Source
Thrown at internal/storage/schema/backfill.go:21
import (
"context"
"database/sql"
"fmt"
"log"
"strings"
"github.com/steveyegge/beads/internal/storage/issueops"
"github.com/steveyegge/beads/internal/types"
)
func ensureBackfilledCustomStatusesCustomTypes(ctx context.Context, db DBConn) (bool, error) {
typesWrote, err := backfillCustomTypes(ctx, db)
if err != nil {
return typesWrote, fmt.Errorf("backfill custom_types: %w", err)
}
statusesWrote, err := backfillCustomStatuses(ctx, db)
if err != nil {
return typesWrote || statusesWrote, fmt.Errorf("backfill custom_statuses: %w", err)
}
return typesWrote || statusesWrote, nil
}
func needsBackfilledCustomStatusesCustomTypes(ctx context.Context, db DBConn) (bool, error) {
typesNeed, err := needsCustomTypesBackfill(ctx, db)
if err != nil {
return false, fmt.Errorf("custom_types: %w", err)
}
statusesNeed, err := needsCustomStatusesBackfill(ctx, db)
if err != nil {
return false, fmt.Errorf("custom_statuses: %w", err)
}
return typesNeed || statusesNeed, nil
}
func needsCustomTypesBackfill(ctx context.Context, db DBConn) (bool, error) {
var count intView on GitHub (pinned to 71377f2769)
Solutions
- Re-run the migration; ensure all numbered migrations execute before the backfill so custom_statuses exists.
- Restore connectivity or unlock the database and retry MigrateUp.
- Grant the DB user SELECT/INSERT on custom_statuses and the config table.
- Read the wrapped cause to target the exact statement that failed.
Defensive patterns
Strategy: retry
Validate before calling
// Confirm custom_statuses exists before the migration backfill stage
var n int
err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'custom_statuses'`).Scan(&n)
if err == nil && n == 0 {
return fmt.Errorf("custom_statuses missing; run full migration chain first")
} Try / catch
err := migrateUp(ctx)
if err != nil && strings.Contains(err.Error(), "backfill custom_statuses:") {
if isTransient(err) {
err = migrateUp(ctx) // seeding is idempotent (INSERT IGNORE, count-gated)
}
} Prevention
- Run migrations to completion before other tooling touches the DB
- Grant the migration user INSERT on custom_statuses
- Avoid killing `bd` mid-upgrade; let MigrateUp finish
- Back up before schema upgrades
When it happens
Trigger: backfillCustomStatuses errors on SELECT COUNT(*) FROM custom_statuses, reading the statuses config key, or INSERT IGNORE INTO custom_statuses (name, category) — typically because the table is missing, the connection dropped, or privileges are insufficient.
Common situations: Partially migrated database (custom_statuses not created yet); read-only or restricted DB user; concurrent lock on custom_statuses; server restart during upgrade.
Related errors
- %s: %w
- backfill custom_types: %w
- backfilling dependencies.id for migration 0053: %w
- backfilling wisp_dependencies split targets for migration 00
- backfill custom tables: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f6e026930f09c5b6.
Report an issue: GitHub.