{"record":{"id":"0d68551ca337f8f8","repo":"t8y2/dbx","slug":"strings-join-failures-0d6855","errorCode":null,"errorMessage":"${strings.Join(failures, \"; \")}","messagePattern":"\\$\\{strings\\.Join\\(failures, \"; \"\\)\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"agents/drivers/hive-go/query.go","lineNumber":279,"sourceCode":"\t\treturn false\n\t}\n\tdelete(server.querySessions, sessionID)\n\tstate.cancel()\n\t_ = state.rows.Close()\n\treturn true\n}\n\nfunc (server *server) closeAllQuerySessions() error {\n\tvar failures []string\n\tfor sessionID, state := range server.querySessions {\n\t\tdelete(server.querySessions, sessionID)\n\t\tstate.cancel()\n\t\tif err := state.rows.Close(); err != nil {\n\t\t\tfailures = append(failures, fmt.Sprintf(\"%s: %v\", sessionID, err))\n\t\t}\n\t}\n\tif len(failures) > 0 {\n\t\treturn errors.New(strings.Join(failures, \"; \"))\n\t}\n\treturn nil\n}\n\nfunc (server *server) expireIdleQuerySessions(now time.Time) int {\n\texpired := make([]string, 0)\n\tfor sessionID, state := range server.querySessions {\n\t\tif !state.lastAccessed.IsZero() && now.Sub(state.lastAccessed) >= querySessionIdleTime {\n\t\t\texpired = append(expired, sessionID)\n\t\t}\n\t}\n\tfor _, sessionID := range expired {\n\t\tserver.closeQuerySession(sessionID)\n\t}\n\treturn len(expired)\n}\n\nfunc (server *server) executeStatements(params map[string]json.RawMessage, transaction bool) (queryResult, error) {","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/hive-go/query.go#L261-L297","documentation":"closeAllQuerySessions tears down every open Hive session during disconnect. If any individual session fails to cancel or close its rows, the session ID and error are accumulated and joined with ';' into a single aggregated error. It signals that disconnect completed only partially and some server-side session resources may be leaked.","triggerScenarios":"Calling disconnect while one or more query sessions still have open rows whose Close() returns an error (e.g. network drop to HiveServer2 mid-close, session already expired server-side).","commonSituations":"App shutdown with long-running queries still streaming; idle sessions already reaped by the server's idle timeout; transient network failure between client and Hive when closing the last result set.","solutions":["Inspect the joined message for the failing session ID and check HiveServer2 logs for that session's teardown errors","Retry disconnect after a short delay; on retry the session list may already be empty","Ensure queries are fully drained (rows.Close() called by the caller) before calling disconnect","Check network connectivity / HiveServer2 availability; a dead connection often makes Close() fail"],"exampleFix":"// before\nif err := server.disconnect(ctx); err != nil {\n    return err // aborts shutdown on one stale session\n}\n// after\nif err := server.disconnect(ctx); err != nil {\n    log.Warnf(\"partial disconnect: %v\", err) // log and continue teardown\n    return nil\n}","handlingStrategy":"try-catch","validationCode":"// Go\nfunc sessionsHealthy(s *server) bool {\n    for _, st := range s.sessions {\n        if st.rows == nil { return false }\n    }\n    return true\n}","typeGuard":"// Go\nif state == nil || state.rows == nil {\n    continue // skip sessions without open rows\n}","tryCatchPattern":"if err := server.disconnect(ctx); err != nil {\n    var agg interface{ SessionIDs() []string }\n    if errors.As(err, &agg) { log.Warnf(\"sessions failed to close: %v\", agg.SessionIDs()) }\n    log.Warnf(\"partial disconnect: %v\", err)\n}","preventionTips":["Drain and Close result sets as soon as queries finish, not at disconnect","Call disconnect during graceful shutdown with adequate timeout","Monitor HiveServer2 session-expiry settings and keep client idle timeouts aligned"],"tags":["go","hive","session-cleanup","disconnection"],"backgroundTag":"session-close-failure","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}