gastownhall/beads · error
counting unbackfilled dependencies.id rows for migration 005
Error message
counting unbackfilled dependencies.id rows for migration 0053: %w
What it means
The migration 0053 repair counts rows in `dependencies` whose `id` is still NULL before making the column NOT NULL and keying it. This error wraps a failure of that `SELECT COUNT(*) FROM dependencies WHERE id IS NULL` probe itself — the count query failed, so the repair cannot safely proceed.
Source
Thrown at internal/storage/schema/migration_repairs.go:516
`, id, e.issueID, e.dependsOnIssueID, e.dependsOnWispID, e.dependsOnExternal); err != nil {
return fmt.Errorf("backfilling dependencies.id for migration 0053: %w", err)
}
}
return nil
}
// ensureDependenciesIDPrimaryKey finishes restoring dependencies.id to 0043's
// canonical shape: NOT NULL and the table's PRIMARY KEY. It re-verifies both
// independently of whether this pass just backfilled anything, so a re-entry
// after a crash between the backfill and the key (or between MODIFY NOT NULL
// and ADD PRIMARY KEY) finishes the remaining step(s) instead of re-running
// ones already done -- MODIFY COLUMN restating an identical definition and
// re-adding an already-present PRIMARY KEY are otherwise either redundant or
// outright rejected as a duplicate key.
func ensureDependenciesIDPrimaryKey(ctx context.Context, db DBConn) error {
var remainingNull int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dependencies WHERE id IS NULL").Scan(&remainingNull); err != nil {
return fmt.Errorf("counting unbackfilled dependencies.id rows for migration 0053: %w", err)
}
if remainingNull > 0 {
// Fail with an actionable count now rather than let a subsequent
// MODIFY COLUMN ... NOT NULL below abort with a generic "column
// cannot be null" error, or silently key the table while leaving
// NULL-id rows behind it.
return fmt.Errorf("migration 0053: %d dependencies row(s) have no depends_on_issue_id/depends_on_wisp_id/depends_on_external target and cannot be assigned an id (ck_dep_one_target should prevent this); repair manually before retrying", remainingNull)
}
idIsPrimaryKey, err := schemaColumnInPrimaryKey(ctx, db, "dependencies", "id")
if err != nil {
return fmt.Errorf("checking dependencies.id primary key: %w", err)
}
if idIsPrimaryKey {
return nil
}
if _, err := db.ExecContext(ctx, "ALTER TABLE dependencies MODIFY COLUMN id CHAR(36) NOT NULL"); err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Rerun `bd` so the repair retries; the probe is idempotent
- Inspect the wrapped %w error for the real cause (no such table, permission denied, connection refused) and address it
- Verify the table exists: query information_schema or run `bd dolt sql -q 'SHOW TABLES'`
- If the schema is badly half-migrated, restore the database from backup and run migrations once, uninterrupted
Example fix
// before: half-migrated db crashes on every bd invocation // after: restore snapshot, rerun once cp -rf backup/beads-db .beads/beads-db ; bd ready
Defensive patterns
Strategy: retry
Validate before calling
bd dolt sql -q 'SHOW TABLES LIKE "dependencies"' || echo 'missing/corrupt table'
Try / catch
if err := ensureSchema(ctx, db); err != nil {
if strings.Contains(err.Error(), "counting unbackfilled dependencies.id") && transient(err) {
return retryWithBackoff(ensureSchema)
}
return fmt.Errorf("schema repair failed: %w", err)
} Prevention
- Do not interrupt bd mid-migration (avoid supervisor kill loops)
- Use a DB account with SELECT on all beads tables
- Monitor Dolt server logs during upgrades
- Back up the database before upgrading
When it happens
Trigger: ensureDependenciesIDPrimaryKey runs during startup schema repair and `db.QueryRowContext(...).Scan(&remainingNull)` errors: table missing/corrupt, connection lost, permissions revoked on dependencies, or Dolt server crashed mid-migration after the column was added but before the primary key was restored.
Common situations: Interrupted first upgrade to 0053 leaving the schema half-migrated; database file corruption or failed Dolt merge; running bd with a database user lacking SELECT on dependencies.
Related errors
- failed to recompute is_blocked: %w
- failed to scan peer for migration: %w
- failed to iterate peers for migration: %w
- failed to update encrypted password for peer %s: %w
- failed to scan federation peer: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/04766707c149089c.
Report an issue: GitHub.