gastownhall/beads · error
checking dependencies.id: %w
Error message
checking dependencies.id: %w
What it means
This wraps failure of schemaColumnExists when ensureDependenciesIDColumn checks whether `dependencies.id` exists as part of the migration-0053 repair (adding a CHAR(36) id, backfilling it, and keying it). Each step re-verifies its own target state, so a failing inspection aborts the repair before any DDL. It means the metadata query failed, not that the column is missing.
Source
Thrown at internal/storage/schema/migration_repairs.go:431
// 0053's own "REPLACE INTO dependencies (id, ...)" matches rows on the
// uk_dep_* natural-identity unique keys; an unkeyed id lets a REPLACE that
// hits a row whose old depends_on_wisp_id is NULL (so uk_dep_wisp_target
// doesn't match) fall through to INSERT, duplicating the edge under a new id
// while the stale row survives. Restoring id as the PRIMARY KEY is what makes
// REPLACE's own conflict detection do its job.
//
// This is deliberately re-entrant rather than a single "column present ->
// nil" gate: preMigrationRepair's mutations to a synced table like
// dependencies land in the same atomic per-step commit as migration 0053
// (see runMigrations' dirty-table-snapshot ordering), but a process killed
// mid-repair -- after ADD COLUMN, before the backfill or the key finishes --
// still needs the NEXT open's repair call to finish the job rather than
// short-circuit on "column exists". Every step below re-verifies its own
// target state instead of trusting an earlier step ran to completion.
func ensureDependenciesIDColumn(ctx context.Context, db DBConn) error {
hasID, err := schemaColumnExists(ctx, db, "dependencies", "id")
if err != nil {
return fmt.Errorf("checking dependencies.id: %w", err)
}
if !hasID {
if _, err := db.ExecContext(ctx, "ALTER TABLE dependencies ADD COLUMN id CHAR(36) NULL"); err != nil {
return fmt.Errorf("adding dependencies.id for migration 0053: %w", err)
}
}
if err := backfillDependenciesID(ctx, db); err != nil {
return err
}
return ensureDependenciesIDPrimaryKey(ctx, db)
}
// backfillDependenciesID fills in any dependencies.id still NULL with
// depid.New(issue_id, target) -- the same deterministic id every insert path
// and the post-migration rekeyDependencyIDs pass use (dep_id_backfill.go) --
// so rows with real edges get a real, cross-clone-stable id rather than a
// throwaway placeholder, and rekeyDependencyIDs finds nothing left to correctView on GitHub (pinned to 71377f2769)
Solutions
- Resolve the wrapped driver error first (connectivity/privileges)
- Grant the repair user metadata-read access
- Re-run the repair — every step re-verifies state, so it is safe to retry from the start
Defensive patterns
Strategy: try-catch
Validate before calling
var n int
if err := db.QueryRowContext(ctx,
"SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'dependencies' AND column_name = 'id'").Scan(&n); err != nil {
return fmt.Errorf("cannot inspect dependencies columns: %w", err)
} Try / catch
if err := repairV53RigAndSplitTargets(ctx, db); err != nil {
if strings.Contains(err.Error(), "checking dependencies.id") {
db = reconnect(db)
return repairV53RigAndSplitTargets(ctx, db) // safe: steps re-verify
}
return err
} Prevention
- Verify metadata access before starting the 0053 repair
- Use a stable connection; reconnect on transient failures and retry
- Remember each repair step re-verifies state, so full re-runs are safe
- Test the repair with a restricted-privilege user to surface gaps
When it happens
Trigger: repairV53RigAndSplitTargets (or the direct unit tests) invokes ensureDependenciesIDColumn and schemaColumnExists errors on the dependencies table — lost connection, privilege denial on column metadata, or driver failure.
Common situations: Under-privileged repair users; network interruption during the multi-step 0053 repair; database restarted between repair steps in CI.
Related errors
- checking wisps.is_blocked column: %w
- checking idx_wisps_is_blocked index: %w
- schema: read database name: %w
- schema migration: %w
- adding wisps.is_blocked: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/63180e7ae266a1f1.
Report an issue: GitHub.