{"record":{"id":"f1d86f4dd2a3796f","repo":"gastownhall/beads","slug":"schema-fresh-bootstrap-reset-w","errorCode":null,"errorMessage":"schema: fresh-bootstrap reset: %w","messagePattern":"schema: fresh-bootstrap reset: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/lock.go","lineNumber":301,"sourceCode":"\t\t// database-scoped migration lock is still held. A mismatch, missing\n\t\t// ancestor, probe error, or previously consumed capability returns the\n\t\t// original DirtyTablesError without attempting a destructive reset.\n\t\tif !o.freshBootstrapHeal.capability.consumeIfCurrentIncarnation(\n\t\t\tctx, conn, databaseName, o.freshBootstrapHeal.endpoint,\n\t\t) {\n\t\t\treturn applied, err\n\t\t}\n\n\t\t// Consume occurs before the reset call. Thus a reset error or a\n\t\t// transient failure in the following migration pass cannot re-arm a\n\t\t// second reset in the caller's outer retry loop.\n\t\tfmt.Fprintf(stderr, \"Discarding interrupted-bootstrap working set (%s) and re-running migrations…\\n\",\n\t\t\tstrings.Join(dirtyErr.Tables, \", \"))\n\t\t// Drained, not Exec'd: the very next thing this path does is re-run the\n\t\t// whole MigrateUp pass on this same pinned connection, so an\n\t\t// undrained proc result set here would poison every statement of it.\n\t\tif resetErr := DrainCall(ctx, conn, \"CALL DOLT_RESET('--hard')\"); resetErr != nil {\n\t\t\treturn applied, errors.Join(err, fmt.Errorf(\"schema: fresh-bootstrap reset: %w\", resetErr))\n\t\t}\n\t\tapplied, err = MigrateUp(ctx, conn)\n\t}\n\treturn applied, err\n}\n\n// consumeIfCurrentIncarnation validates and atomically consumes c. All probes\n// run on the same pinned session while MigrateUpWithLock holds the migration\n// lock. Query errors deliberately collapse to false so callers preserve and\n// return the original DirtyTablesError.\nfunc (c *FreshBootstrapHealCapability) consumeIfCurrentIncarnation(\n\tctx context.Context,\n\tconn *sql.Conn,\n\tdatabaseName string,\n\tendpoint string,\n) bool {\n\tif c == nil || c.consumed.Load() {\n\t\treturn false","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/lock.go#L283-L319","documentation":"During the fresh-bootstrap self-heal, after the dirty-tables guard fired, the library runs `CALL DOLT_RESET('--hard')` (drained on the pinned session). If that reset fails, the original DirtyTablesError is joined with this reset error and returned. This is a destructive recovery step failing, so migrations could not be re-run from a clean slate.","triggerScenarios":"MigrateUpWithLock with WithFreshBootstrapHeal where MigrateUp returns DirtyTablesError, the capability validates and is consumed, but DOLT_RESET errors — server error, connection drop, or the proc result cannot be drained.","commonSituations":"Interrupted bootstrap left dirty tables AND the server is unhealthy (restart, disk full, permissions); a pinned session corrupted by earlier undrained result sets.","solutions":["Inspect both joined errors; fix the reset cause (connectivity, server health) before retrying.","Retry the open: the capability is consumed, so a retry takes the normal path; manually run DOLT_RESET('--hard') if you've confirmed the working set is disposable.","Check server logs for why DOLT_RESET failed (read-only filesystem, lock conflicts).","As a last resort drop and recreate the database if it's genuinely fresh/disposable."],"exampleFix":"// before\n// capability consumed, reset failed; blind outer retry does nothing\n// after\n// verify and reset manually once server is healthy:\n// CALL DOLT_RESET('--hard');\napplied, err := schema.MigrateUpWithLock(ctx, conn, dbName)","handlingStrategy":"try-catch","validationCode":"// before opting into heal, confirm reset is acceptable:\n// the database must be freshly created this logical open (hold the capability)\nif cap == nil { /* heal disabled; dirty tables are fatal */ }","typeGuard":"var dirtyErr *schema.DirtyTablesError\nif errors.As(err, &dirtyErr) && strings.Contains(err.Error(), \"fresh-bootstrap reset\") {\n    // heal reset itself failed\n}","tryCatchPattern":"applied, err := schema.MigrateUpWithLock(ctx, conn, db, schema.WithFreshBootstrapHeal(cap, endpoint))\nif err != nil && strings.Contains(err.Error(), \"fresh-bootstrap reset\") {\n    // capability already consumed; fix server health, then either\n    // run CALL DOLT_RESET('--hard') manually or drop/recreate the db\n}","preventionTips":["Verify server health (disk, restarts) before enabling the heal path.","Remember the capability is one-shot: a failed reset requires manual intervention on retry.","Check pinned-session hygiene (no undrained result sets) before the reset call.","Keep an operator runbook for manually disposing interrupted-bootstrap working sets."],"tags":["go","database","dolt","bootstrap","reset"],"backgroundTag":"dolt-reset-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}