{"record":{"id":"827e47b9c95bf99c","repo":"wavetermdev/waveterm","slug":"connection-q-is-not-connected","errorCode":null,"errorMessage":"connection %q is not connected","messagePattern":"connection %q is not connected","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/jobcontroller/jobcontroller.go","lineNumber":592,"sourceCode":"\t\tif status == JobConnStatus_Connected {\n\t\t\tcount++\n\t\t}\n\t}\n\treturn count\n}\n\nfunc CheckJobConnected(ctx context.Context, jobId string) (*waveobj.Job, error) {\n\tjob, err := wstore.DBMustGet[*waveobj.Job](ctx, jobId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get job: %w\", err)\n\t}\n\n\tisConnected, err := conncontroller.IsConnected(job.Connection)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error checking connection status: %w\", err)\n\t}\n\tif !isConnected {\n\t\treturn nil, fmt.Errorf(\"connection %q is not connected\", job.Connection)\n\t}\n\n\tjobConnStatus := GetJobConnStatus(jobId)\n\tif jobConnStatus != JobConnStatus_Connected {\n\t\treturn nil, fmt.Errorf(\"job is not connected (status: %s)\", jobConnStatus)\n\t}\n\n\treturn job, nil\n}\n\ntype StartJobParams struct {\n\tConnName string\n\tJobKind  string\n\tCmd      string\n\tArgs     []string\n\tEnv      map[string]string\n\tTermSize *waveobj.TermSize\n\tBlockId  string","sourceCodeStart":574,"sourceCodeEnd":610,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/jobcontroller/jobcontroller.go#L574-L610","documentation":"CheckJobConnected returns this error when conncontroller.IsConnected answers definitively that the job's connection is not currently connected. The job and connection exist, but the underlying transport (e.g. SSH) is down.","triggerScenarios":"Calling CheckJobConnected (via doReconnectJob or SendInput) when the job's connection is configured but disconnected — dropped SSH session, remote host unreachable, or connection not yet established.","commonSituations":"Laptop slept and SSH dropped; remote host rebooted; network switch/VPN down; trying to send input before the remote shell connects.","solutions":["Reconnect the connection (wait for doReconnectJob or trigger reconnection)","Check network/SSH reachability of the remote host","Retry once the connection reports connected","Route input through a queue and flush when reconnected"],"exampleFix":"// before\n_, err := jobcontroller.CheckJobConnected(ctx, jobId)\nif err != nil {\n\treturn err\n}\n// after\n_, err := jobcontroller.CheckJobConnected(ctx, jobId)\nif err != nil {\n\tvar connErr *jobcontroller.NotConnectedError // or message check\n\tif strings.Contains(err.Error(), \"is not connected\") {\n\t\t<-reconnectedCh\n\t\t_, err = jobcontroller.CheckJobConnected(ctx, jobId)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n}","handlingStrategy":"retry","validationCode":"isConn, _ := conncontroller.IsConnected(connName)\nif !isConn {\n\treturn fmt.Errorf(\"pre-flight: connection %s down; reconnect first\", connName)\n}","typeGuard":"func isNotConnectedErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"is not connected\")\n}","tryCatchPattern":"_, err := jobcontroller.CheckJobConnected(ctx, jobId)\nif isNotConnectedErr(err) {\n\tselect {\n\tcase <-reconnectedCh:\n\t\t_, err = jobcontroller.CheckJobConnected(ctx, jobId)\n\tcase <-time.After(10 * time.Second):\n\t\treturn fmt.Errorf(\"timed out waiting for reconnection\")\n\t}\n}\nif err != nil { return err }","preventionTips":["Gate SendInput behind connection state instead of calling blindly","Handle sleep/resume by proactively reconnecting","Monitor SSH/VPN health for remote jobs","Queue input during disconnections and flush on reconnect"],"tags":["network","ssh","disconnected"],"backgroundTag":"connection-not-connected","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}