gastownhall/beads · error
checking dirty tables against pending ignored migrations: %w
Error message
checking dirty tables against pending ignored migrations: %w
What it means
This error wraps a failure in ignoredSource.pendingMigrationDirtyTables - the mid-pass re-check of whether pending ignored-source migrations would alter pre-existing dirty tables. Unlike a positive finding (which yields the plain table-list error at 4009), this is the check itself erroring out, after main migrations already applied.
Source
Thrown at internal/storage/schema/schema.go:695
// migration 0037 randomized per-clone, the same hazard class on the aux
// tables. Gated on the clone-local ignored marker (recorded later in this
// pass by ignoredSource.migrate) so it runs exactly once per clone instead
// of churning synced rows on every later migration pass — and on the
// pre-pass main cursor, so fresh clones of converged lineages record the
// marker without re-running the rewrite (bd-578h9.4).
// ...and the bd-ri8bd sibling: one more pass over the same tables for the
// rows minted with random UUIDv7 ids between the initial backfill and the
// switch to content-derived ids at insert time. Same machinery, own
// marker/sentinel/shipped-version gates, one shared cursor read.
auxRekeyed, err := rekeyAuxRowIDsAllPasses(ctx, db, mainVersionBefore)
if err != nil {
return applied, fmt.Errorf("rekey aux row ids: %w", err)
}
backfilled = backfilled || auxRekeyed
touchedIgnoredDirtyTables, err := ignoredSource.pendingMigrationDirtyTables(ctx, db, dirtyBeforeAll)
if err != nil {
return applied, fmt.Errorf("checking dirty tables against pending ignored migrations: %w", err)
}
if len(touchedIgnoredDirtyTables) > 0 {
// Deliberately a plain, untyped error (unlike the main-source guard
// above, which returns *DirtyTablesError): this check fires mid-pass,
// after the main-source migrations have already applied. A lenient
// caller (embeddeddolt's openReadOnlyCommand / openWorkingSetReconcile
// intents) skipping this and returning as if the open succeeded would
// let a reconcile commit checkpoint a half-applied migration pass.
// The ignored source also tracks bd-internal state (dolt_ignore'd
// tables like ignored_schema_migrations), not expected user data, so
// there is no dirty-commit recovery story to support here the way
// there is for the main-source guard (#4566 scope).
return applied, fmt.Errorf("pending ignored schema migrations alter pre-existing dirty tables: %s", strings.Join(touchedIgnoredDirtyTables, ", "))
}
appliedIgnored, ignoredColumnAdded, err := ignoredSource.migrate(ctx, db, 0)
if err != nil {
return applied, fmt.Errorf("ignored migrations: %w", err)View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause for the failing ignored-source query
- Repair or restore ignored_schema_migrations / dolt_ignore'd internal tables from a healthy clone
- Eliminate concurrent writers for the duration of MigrateUp
- Re-run MigrateUp once the internal tables are readable
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure internal ignored tables are queryable before opening
if _, err := db.QueryContext(ctx, "SELECT 1 FROM ignored_schema_migrations LIMIT 1"); err != nil {
return fmt.Errorf("internal migration tables unreadable: %w", err)
} Type guard
func isIgnoredDirtyCheckErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "checking dirty tables against pending ignored migrations")
} Try / catch
applied, err := schema.MigrateUp(ctx, db)
if isIgnoredDirtyCheckErr(err) {
return fmt.Errorf("mid-pass check failed after %d main migrations: %w", applied, err)
} Prevention
- Never delete or hand-modify dolt_ignore'd internal tables
- Copy complete databases including ignored tables
- Run one bd process per repository during upgrades
When it happens
Trigger: Calling MigrateUp/MigrateUpWithLock where the ignored-source dirty-table cross-check fails - Dolt query errors against dolt_ignore'd internal tables (ignored_schema_migrations), malformed ignored migration metadata, or engine errors mid-pass.
Common situations: Databases where the ignored source's tables were damaged or copied incompletely; concurrent writers invalidating the earlier dirty snapshot mid-pass; read-only opens that fail on internal writes.
Related errors
- checking dirty tables against pending migrations: %w
- reading pre-migration dirty table diffs: %w
- pending ignored schema migrations alter pre-existing dirty t
- failed to migrate credential keys: %w
- failed to update encrypted password for peer %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9e5f8cf3032da197.
Report an issue: GitHub.