gastownhall/beads · warning
server: DoltServer.Stop: %w
Error message
server: DoltServer.Stop: %w
What it means
Stop() runs a shutdown GC (DOLT_GC and DOLT_STATS_GC over a SQL connection) before killing the dolt child; this error wraps any failure from runShutdownGC. The returned error is an errors.Join of GC, wait, log-close, and pidfile-remove errors, so the stop itself still proceeds.
Source
Thrown at internal/storage/dbproxy/server/doltserver.go:351
if time.Now().After(deadline) {
return fmt.Errorf("listener not ready after %s: %w", startReadyTimeout, err)
}
select {
case <-ctx.Done():
return ctx.Err()
case <-s.egCtx.Done():
return errors.New("dolt sql-server exited before listener became ready")
case <-time.After(startReadyPollInterval):
}
}
}
func (s *DoltServer) Stop(ctx context.Context) error {
gcErr := s.runShutdownGC(ctx)
if gcErr != nil {
gcErr = fmt.Errorf("server: DoltServer.Stop: %w", gcErr)
}
if s.cancel != nil {
s.cancel()
}
var waitErr error
if s.eg != nil {
waitErr = s.eg.Wait()
var exitErr *exec.ExitError
if errors.As(waitErr, &exitErr) || errors.Is(waitErr, context.Canceled) {
waitErr = nil
}
}
if waitErr != nil {
waitErr = fmt.Errorf("server: DoltServer.Stop: %w", waitErr)
}
var closeErr error
if s.logFile != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Check whether the error is connection-level — if the server is already dead, this is benign and the shutdown still completed.
- Retry Stop with a fresh, non-cancelled context so GC connections can be established.
- Run `CALL DOLT_GC()` manually via a SQL client to see the underlying GC error.
- Ensure no long-running queries/transactions are holding back GC before calling Stop.
Example fix
// before
ctx, cancel := context.WithCancel(ctx) // already-cancelled ctx starves shutdown GC
cancel()
_ = srv.Stop(ctx)
// after
gcCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Stop(gcCtx); err != nil {
log.Warnf("stop returned errors: %v", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Only pass a live context to Stop; a cancelled ctx starves shutdown GC.
if ctx.Err() != nil {
ctx = context.Background()
} Try / catch
if err := srv.Stop(gcCtx); err != nil {
if strings.Contains(err.Error(), "gc connection") || strings.Contains(err.Error(), "DOLT_GC") {
log.Warnf("shutdown GC failed (server still shut down): %v", err)
return nil // treat GC failure as non-fatal to shutdown
}
return err
} Prevention
- Call Stop with a fresh context, not one derived from an already-cancelled request scope.
- Let long queries finish before stopping to avoid GC blocking.
- Verify the dolt version supports DOLT_STATS_GC.
- Treat Stop's joined errors individually — GC failure does not mean the server failed to stop.
When it happens
Trigger: runShutdownGC fails: the server is Running but the SQL connection cannot be opened/acquired (server already wedged, wrong DSN/TLS settings), or the CALL DOLT_GC / DOLT_STATS_GC statements error (e.g. GC fails due to table corruption or insufficient privileges).
Common situations: Server half-dead so connections time out during shutdown; GC blocked by long-running transactions; dolt version where DOLT_STATS_GC doesn't exist; ctx passed to Stop already cancelled/expired.
Related errors
- acquire connection for gc: %w
- %s close timed out after %v
- ErrUnverifiableProcess
- errStartInterrupted
- ErrTransaction
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d00e9514f9bf6125.
Report an issue: GitHub.