gastownhall/beads · critical

failed to start dolt server after %d attempts: %w Corrupt ma

Error message

failed to start dolt server after %d attempts: %w
Corrupt manifest with no recoverable data detected (GH#3290) in:
  %s
Run 'bd doctor --fix' to back up the corrupt database(s) and reinitialize.
Check logs: %s

What it means

After all start attempts fail, Start() checks detectCorruptManifest(beadsDir, doltDir). If an unclean shutdown left a corrupt .dolt manifest with no recoverable data (GH#3290 / bd-6dnrw.6), the error is augmented with the affected directories and an instruction to run 'bd doctor --fix'. Repair is deliberately not automatic because reinitializing .dolt is destructive.

Source

Thrown at internal/doltserver/doltserver.go:1470

				lastErr = fmt.Errorf("dolt sql-server exited immediately on port %d (attempt %d/%d)", actualPort, i+1, attempts)
				pid = 0
				if !explicitPort {
					continue
				}
				break
			}

			lastErr = nil
			break
		}
		_ = logFile.Close()

		if lastErr != nil {
			// GH#3290 / bd-6dnrw.6: unclean-shutdown manifest corruption is
			// detected here but never auto-repaired — reinitializing .dolt is
			// destructive, so repair stays behind explicit bd doctor --fix.
			if dirs, detErr := detectCorruptManifest(beadsDir, doltDir); detErr == nil && len(dirs) > 0 {
				return nil, fmt.Errorf("failed to start dolt server after %d attempts: %w\n"+
					"Corrupt manifest with no recoverable data detected (GH#3290) in:\n  %s\n"+
					"Run 'bd doctor --fix' to back up the corrupt database(s) and reinitialize.\nCheck logs: %s",
					attempts, lastErr, strings.Join(dirs, "\n  "), logPath(beadsDir))
			}
			return nil, fmt.Errorf("failed to start dolt server after %d attempts: %w\nCheck logs: %s",
				attempts, lastErr, logPath(beadsDir))
		}
	}

	// Write PID and port files
	if err := os.WriteFile(pidPath(beadsDir), []byte(strconv.Itoa(pid)), 0600); err != nil {
		if proc, findErr := os.FindProcess(pid); findErr == nil {
			_ = proc.Kill()
		}
		return nil, fmt.Errorf("writing PID file: %w", err)
	}
	if err := writePortFile(beadsDir, actualPort); err != nil {
		if proc, findErr := os.FindProcess(pid); findErr == nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run bd doctor --fix to back up the corrupt database(s) and reinitialize the affected .dolt directories.
  2. Restore the data dir from a good backup/git remote (bd dolt pull) instead of reinitializing if data must be preserved.
  3. Fix the root cause of unclean shutdowns (avoid SIGKILL, ensure clean OS shutdown, check disk health).
  4. Re-sync from the git remote after repair: bd dolt pull.

Example fix

// before
bd start
// failed to start ... Corrupt manifest (GH#3290) in: ~/.beads/.dolt/...
// after
bd doctor --fix
bd dolt pull
bd start
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check manifest health before starting
const manifest = path.join(dataDir, '.dolt', 'noms', 'manifest.json');
try { JSON.parse(await fs.readFile(manifest, 'utf8')); }
catch { console.error('manifest unreadable — run bd doctor --fix'); }

Type guard

null

Try / catch

try {
  await bdStart();
} catch (e) {
  if (/Corrupt manifest/.test(e.message)) {
    await run('bd', ['doctor', '--fix']);  // backs up + reinitializes
    await run('bd', ['dolt', 'pull']);     // restore from remote
    return bdStart();
  }
  throw e;
}

Prevention

When it happens

Trigger: All spawn attempts exhausted (lastErr set, commonly bind failures or immediate exits) AND detectCorruptManifest finds corrupt manifest directories.

Common situations: Machine lost power or the process was SIGKILLed mid-write, leaving a truncated/invalid manifest; Dolt data dir restored from a partial backup.

Related errors


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