{"record":{"id":"85abdacf72d0ee9f","repo":"wavetermdev/waveterm","slug":"cannot-open-domain-socket-for-q-when-status-is-q","errorCode":null,"errorMessage":"cannot open domain socket for %q when status is %q","messagePattern":"cannot open domain socket for %q when status is %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/conncontroller/conncontroller.go","lineNumber":276,"sourceCode":"\nfunc (conn *SSHConn) GetStatus() string {\n\tconn.lock.Lock()\n\tdefer conn.lock.Unlock()\n\treturn conn.Status\n}\n\nfunc (conn *SSHConn) GetName() string {\n\t// no lock required because opts is immutable\n\treturn conn.Opts.String()\n}\n\nfunc (conn *SSHConn) OpenDomainSocketListener(ctx context.Context) error {\n\tconn.Infof(ctx, \"running OpenDomainSocketListener...\\n\")\n\tallowed := WithLockRtn(conn, func() bool {\n\t\treturn conn.Status == Status_Connecting\n\t})\n\tif !allowed {\n\t\treturn fmt.Errorf(\"cannot open domain socket for %q when status is %q\", conn.GetName(), conn.GetStatus())\n\t}\n\tclient := conn.GetClient()\n\trandStr, err := utilfn.RandomHexString(16) // 64-bits of randomness\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error generating random string: %w\", err)\n\t}\n\tsockName := fmt.Sprintf(\"/tmp/waveterm-%s.sock\", randStr)\n\tconn.Infof(ctx, \"generated domain socket name %s\\n\", sockName)\n\tlistener, err := client.ListenUnix(sockName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to request connection domain socket: %v\", err)\n\t}\n\tconn.WithLock(func() {\n\t\tconn.DomainSockName = sockName\n\t\tconn.DomainSockListener = listener\n\t})\n\tconn.Infof(ctx, \"successfully connected domain socket\\n\")\n\tgo func() {","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/remote/conncontroller/conncontroller.go#L258-L294","documentation":"OpenDomainSocketListener may only run while the SSH connection is in the Status_Connecting state; the check is done under the connection lock. If the connection has already moved past (Connected, Connecting-again, Disconnected, etc.), opening the wsh domain socket listener is refused with this error.","triggerScenarios":"tryEnableWsh calls OpenDomainSocketListener after the connection status changed from Status_Connecting — e.g. a duplicate enable attempt, or the connection finished connecting meanwhile.","commonSituations":"wsh auto-enable racing with connection establishment; calling tryEnableWsh twice on the same connection; attempting wsh enable on an already-connected or disconnected connection.","solutions":["Ensure OpenDomainSocketListener is invoked exactly once during the connecting phase (guard with a 'wsh tried' flag)","Re-check conn.Status before calling and skip if it is not Status_Connecting","If wsh is needed on an already-connected connection, restart the connection (disconnect/reconnect) so it re-enters Status_Connecting"],"exampleFix":"// before\nconn.OpenDomainSocketListener(ctx) // status may already be Connected\n// after\nif conn.GetStatus() != remote.Status_Connecting {\n    return // or reconnect first\n}\nif err := conn.OpenDomainSocketListener(ctx); err != nil {\n    log.Printf(\"wsh socket skipped: %v\", err)\n}","handlingStrategy":"validation","validationCode":"if conn.GetStatus() != remote.Status_Connecting {\n    return fmt.Errorf(\"skip OpenDomainSocketListener: status is %s\", conn.GetStatus())\n}","typeGuard":null,"tryCatchPattern":"err := conn.OpenDomainSocketListener(ctx)\nif err != nil && strings.Contains(err.Error(), \"cannot open domain socket\") {\n    log.Printf(\"wsh socket setup skipped: %v\", err) // not fatal; skip\n}","preventionTips":["Invoke OpenDomainSocketListener only from the connecting phase, exactly once","Use a once-flag so tryEnableWsh cannot race itself","If already connected, reconnect rather than forcing the listener"],"tags":["ssh","connection-state","wsh"],"backgroundTag":"invalid-connection-state","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}