{"record":{"id":"7fda9329d73b1520","repo":"gastownhall/beads","slug":"s-close-timed-out-after-v","errorCode":null,"errorMessage":"%s close timed out after %v","messagePattern":"(.+?) close timed out after (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/storage/doltutil/close.go","lineNumber":34,"sourceCode":"func CloseWithTimeout(name string, closeFn func() error) error {\n\ttimer := time.NewTimer(CloseTimeout)\n\tdefer timer.Stop()\n\n\treturn closeWithDeadline(name, closeFn, timer.C)\n}\n\nfunc closeWithDeadline(name string, closeFn func() error, deadline <-chan time.Time) error {\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- closeFn()\n\t}()\n\n\tselect {\n\tcase err := <-done:\n\t\treturn err\n\tcase <-deadline:\n\t\t// Close is hanging - log and continue rather than blocking forever\n\t\treturn fmt.Errorf(\"%s close timed out after %v\", name, CloseTimeout)\n\t}\n}\n","sourceCodeStart":16,"sourceCodeEnd":37,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/doltutil/close.go#L16-L37","documentation":"closeWithDeadline guards database Close calls that can hang. If the close does not finish within CloseTimeout, the library gives up waiting and returns '%s close timed out after %v' so callers are not blocked forever. The close may still complete later in the background.","triggerScenarios":"Calling CloseWithTimeout (or Close paths using closeWithDeadline) on a Dolt store whose underlying close blocks — e.g. in-flight queries, hung Dolt engine process, or an open transaction blocking shutdown.","commonSituations":"Long-running query still executing at shutdown; Dolt subprocess wedged; many open connections draining slowly; disk I/O stall.","solutions":["Wait past CloseTimeout and verify the process/database eventually released resources.","Find and cancel in-flight queries/transactions before closing.","Kill a hung embedded Dolt process if it never finishes closing.","Increase CloseTimeout if legitimate large closes need more time."],"exampleFix":"// before\ndefer store.Close() // may hang\n// after\nif err := doltutil.CloseWithTimeout(store, 5*time.Second); err != nil {\n    log.Printf(\"close problem (continuing): %v\", err)\n}","handlingStrategy":"fallback","validationCode":"// ensure no in-flight work before closing:\n// wg.Wait() on outstanding queries/transactions","typeGuard":null,"tryCatchPattern":"if err := doltutil.CloseWithTimeout(store, 5*time.Second); err != nil {\n    log.Printf(\"close timed out, continuing: %v\", err) // non-fatal\n}","preventionTips":["Cancel outstanding queries before Close","Avoid holding transactions across long waits","Treat close timeout as a warning, not a data-loss signal","Use CloseWithTimeout on every shutdown path"],"tags":["timeout","database","shutdown"],"backgroundTag":"close-timeout","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}