{"record":{"id":"a61664f68d6c4c44","repo":"wavetermdev/waveterm","slug":"client-q-not-found-a61664","errorCode":null,"errorMessage":"client %q not found","messagePattern":"client %q not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/wslconn/wslconn.go","lineNumber":783,"sourceCode":"\tconnStatus := conn.DeriveConnStatus()\n\tswitch connStatus.Status {\n\tcase Status_Connected:\n\t\treturn nil\n\tcase Status_Connecting:\n\t\treturn conn.WaitForConnect(ctx)\n\tcase Status_Init, Status_Disconnected:\n\t\treturn conn.Connect(ctx)\n\tcase Status_Error:\n\t\treturn fmt.Errorf(\"connection error: %s\", connStatus.Error)\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown connection status %q\", connStatus.Status)\n\t}\n}\n\nfunc DisconnectClient(connName string) error {\n\tconn := getConnInternal(connName)\n\tif conn == nil {\n\t\treturn fmt.Errorf(\"client %q not found\", connName)\n\t}\n\terr := conn.Close()\n\treturn err\n}\n","sourceCodeStart":765,"sourceCodeEnd":788,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wslconn/wslconn.go#L765-L788","documentation":"DisconnectClient() looks up the connection via getConnInternal and throws this when no connection with that name exists, before attempting conn.Close(). Note this uses the internal registry lookup, so it also fires for connections that were already closed and removed from the registry.","triggerScenarios":"Calling DisconnectClient with an unknown or already-disconnected-and-forgotten connName — e.g. disconnecting twice, or disconnecting a name that was never connected.","commonSituations":"UI issued two disconnect actions in quick succession (double-click); a shutdown/cleanup routine iterates names from a stale snapshot while some were already closed; typo in the connection name.","solutions":["Treat the error as idempotent success if the goal is 'make sure it is disconnected' — ignore 'not found'","Check the connection exists first via DeriveConnStatus/GetConnections before disconnecting","Fix double-disconnect paths so cleanup runs exactly once","Verify the connName spelling against the registered connections"],"exampleFix":"// before\nerr := wslconn.DisconnectClient(connName) // 'client \"x\" not found' on second call\n// after\nif st := wslconn.DeriveConnStatusFor(connName); st != nil && st.Status != \"\" {\n    err := wslconn.DisconnectClient(connName)\n    if err != nil && strings.Contains(err.Error(), \"not found\") {\n        err = nil // already disconnected\n    }\n}","handlingStrategy":"validation","validationCode":"st := wslconn.DeriveConnStatusFor(connName)\nif st == nil || st.Status == \"\" {\n    return nil // already gone; nothing to disconnect\n}\nwslconn.DisconnectClient(connName)","typeGuard":null,"tryCatchPattern":"err := wslconn.DisconnectClient(name)\nif err != nil && strings.Contains(err.Error(), \"not found\") {\n    err = nil // idempotent disconnect: already removed\n}","preventionTips":["Make disconnect flows idempotent by ignoring 'not found'","Guard against double-click duplicate disconnect actions","Use a live connection list, not a stale snapshot, for cleanup loops","Track which connections your code owns and closed already"],"tags":["go","connection-lookup","disconnect","lifecycle"],"backgroundTag":"connection-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}