gastownhall/beads · error

adding issues.%s for migration 0053: %w

Error message

adding issues.%s for migration 0053: %w

What it means

Wraps failure of `ALTER TABLE issues ADD COLUMN <name> <definition>` when the 0053 repair adds a missing rig column (`role_type` VARCHAR(32) DEFAULT '' or `rig` VARCHAR(255) DEFAULT ''). Only reached when the column was confirmed absent, so this is the ALTER itself failing.

Source

Thrown at internal/storage/schema/migration_repairs.go:594

func ensureIssuesRigColumns(ctx context.Context, db DBConn) error {
	columns := []struct{ name, definition string }{
		{"hook_bead", "VARCHAR(255) DEFAULT ''"},
		{"role_bead", "VARCHAR(255) DEFAULT ''"},
		{"agent_state", "VARCHAR(32) DEFAULT ''"},
		{"last_activity", "DATETIME"},
		{"role_type", "VARCHAR(32) DEFAULT ''"},
		{"rig", "VARCHAR(255) DEFAULT ''"},
	}
	for _, col := range columns {
		present, err := schemaColumnExists(ctx, db, "issues", col.name)
		if err != nil {
			return fmt.Errorf("checking issues.%s: %w", col.name, err)
		}
		if present {
			continue
		}
		if _, err := db.ExecContext(ctx, "ALTER TABLE issues ADD COLUMN "+col.name+" "+col.definition); err != nil {
			return fmt.Errorf("adding issues.%s for migration 0053: %w", col.name, err)
		}
	}
	return nil
}

// ensureWispDependenciesSplitTargets repairs #4555: a mixed-vintage local
// wisp_dependencies table can have the post-0005 id column while still lacking
// one or more split target columns. Migration 0053 reads those columns when it
// repairs rig wisps, so add the missing columns and backfill them from the
// legacy depends_on_id column when that source column is still available.
//
// Column presence is not, by itself, proof the backfill below ever ran: a
// process killed after the ADD COLUMNs but before the backfill leaves all
// three target columns present but unpopulated. Re-entry must not
// short-circuit on "columns exist" -- it re-runs the backfill whenever
// depends_on_id (the legacy source the backfill reads from) is still around,
// which is itself idempotent (each statement below is scoped to the rows it
// hasn't yet filled in). Skipping this matters because a later ignored

View on GitHub (pinned to 71377f2769)

Solutions

  1. Ensure exclusive access (stop other bd processes) and rerun; presence checks make it idempotent
  2. Free disk space before retrying — ALTER rebuilds the table
  3. Grant ALTER privilege to the database user if the wrapped error says denied
  4. Run the migration in a maintenance window for large databases and suppress restart loops

Example fix

// before: concurrent bd processes deadlock the ALTER
pkill -f 'bd ' ; bd ready   // completes column add
// after: single clean run
bd ready
Defensive patterns

Strategy: retry

Validate before calling

df -h /path/to/db
bd dolt sql -q "SHOW COLUMNS FROM issues LIKE 'rig'" || echo 'issues table busy/unreachable'

Try / catch

if err := ensureSchema(ctx, db); err != nil {
    if strings.Contains(err.Error(), "adding issues.") && strings.Contains(err.Error(), "migration 0053") {
        return retryWithBackoff(ensureSchema) // idempotent: re-checks column presence
    }
    return err
}

Prevention

When it happens

Trigger: ensureIssuesRigColumns finds a column missing and the ADD COLUMN fails: issues table locked by a concurrent writer, missing ALTER privilege, disk full during table rebuild, Dolt transaction conflict, or connection drop on a large issues table.

Common situations: Upgrade of a large production beads database interrupted by process supervisors; simultaneous bd invocations during first run after upgrade; low-disk CI containers.

Related errors


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