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

  1. Rerun `bd` so the repair retries; the probe is idempotent
  2. Inspect the wrapped %w error for the real cause (no such table, permission denied, connection refused) and address it
  3. Verify the table exists: query information_schema or run `bd dolt sql -q 'SHOW TABLES'`
  4. 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

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


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