{"record":{"id":"8a7c23f1e9c7755e","repo":"gastownhall/beads","slug":"stop-database-server-w","errorCode":null,"errorMessage":"stop database server: %w","messagePattern":"stop database server: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/server.go","lineNumber":347,"sourceCode":"\t}\n\tdefer func() { _ = pidfile.Remove(p.rootDir, PIDFileName) }()\n\n\tg, gctx := errgroup.WithContext(ctx)\n\tg.Go(func() error {\n\t\t<-gctx.Done()\n\t\t_ = p.listener.Close()\n\t\t_ = control.Close()\n\t\treturn nil\n\t})\n\tg.Go(func() error { return p.idleWatcher(gctx) })\n\tg.Go(func() error { return p.acceptLoop(gctx) })\n\n\trunErr := g.Wait()\n\t_ = p.conns.Wait()\n\tp.stats.IncBackendStop()\n\tstopErr := stopBackendBounded(p.server)\n\tif stopErr != nil {\n\t\tstopErr = fmt.Errorf(\"stop database server: %w\", stopErr)\n\t}\n\tif errors.Is(runErr, errIdleTimeout) || sigReceived.Load() {\n\t\trunErr = nil\n\t}\n\treturn errors.Join(runErr, stopErr)\n}\n\nfunc stopBackendBounded(s server.DatabaseServer) error {\n\tctx, cancel := context.WithTimeout(context.Background(), backendStopTimeout)\n\tdefer cancel()\n\treturn s.Stop(ctx)\n}\n\nfunc (p *proxyServer) idleWatcher(ctx context.Context) error {\n\tif p.idleTimeout <= 0 {\n\t\t<-ctx.Done()\n\t\treturn nil\n\t}","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/server.go#L329-L365","documentation":"After the proxy run loop finishes, ListenAndServe attempts a bounded stop of the embedded Dolt backend via stopBackendBounded (s.Stop with backendStopTimeout). If that stop returns an error, it is wrapped as 'stop database server: %w' and joined with any run error via errors.Join. This signals the backend may still be running or was not shut down cleanly within the timeout.","triggerScenarios":"The proxy is shutting down (idle timeout, signal, or listener error) and backend Stop(ctx) fails or exceeds backendStopTimeout — e.g. the dolt backend process is wedged, already exited unexpectedly, or the stop command times out.","commonSituations":"Backend hung on a long query or fsync during shutdown; backend killed externally moments before proxy stop; resource exhaustion making the bounded stop time out; SIGKILL'd backend leaving Stop to report failure.","solutions":["Run 'bd dolt stop' again (or proxy.Shutdown) after a short delay — it will verify/quarantine the leftover backend record.","Check for a live dolt backend process (ps aux | grep dolt) and stop or kill it if wedged.","Inspect the wrapped cause after 'stop database server: ' for the concrete Stop failure.","If the backend is genuinely dead, clear stale control files via the proxy's purge path and restart.","Increase headroom on the machine (CPU/IO pressure) if the bounded timeout is routinely exceeded."],"exampleFix":"// before\nerr := proxy.ListenAndServe(...) // returns: stop database server: context deadline exceeded\n// after\nif err != nil && strings.Contains(err.Error(), \"stop database server\") {\n    _ = proxy.Shutdown(rootDir) // verify/quarantine leftover records, then retry start\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight: confirm the backend record and process state are sane\npf, err := pidfile.Read(rootDir, server.PIDFileName)\nif err == nil && pf != nil {\n    if alive := processExists(pf.Pid); alive {\n        // backend currently running; ensure machine headroom for a bounded stop\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := proxy.ListenAndServe(ctx, ...); err != nil {\n    if strings.Contains(err.Error(), \"stop database server\") {\n        // backend may be left running; run proxy.Shutdown to verify/quarantine, then retry\n        if sErr := proxy.Shutdown(rootDir); sErr != nil { /* escalate */ }\n    }\n    return err\n}","preventionTips":["Avoid SIGKILLing the backend; stop it through bd/proxy.Shutdown","Keep CPU/IO headroom so the bounded stop timeout is not exceeded","Re-run Shutdown after any 'stop database server' failure to clean leftovers","Monitor for wedged dolt processes"],"tags":["go","process-management","shutdown","dolt"],"backgroundTag":"backend-stop-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}