wavetermdev/waveterm · error
job is not connected (status: %s)
Error message
job is not connected (status: %s)
What it means
CheckJobConnected performs a two-step check: the raw connection must be up, and GetJobConnStatus(jobId) must return JobConnStatus_Connected. This error means the in-memory job-level connection status disagrees with the transport state — the conn is up but the job itself hasn't (or no longer) registered as connected.
Source
Thrown at pkg/jobcontroller/jobcontroller.go:597
}
func CheckJobConnected(ctx context.Context, jobId string) (*waveobj.Job, error) {
job, err := wstore.DBMustGet[*waveobj.Job](ctx, jobId)
if err != nil {
return nil, fmt.Errorf("failed to get job: %w", err)
}
isConnected, err := conncontroller.IsConnected(job.Connection)
if err != nil {
return nil, fmt.Errorf("error checking connection status: %w", err)
}
if !isConnected {
return nil, fmt.Errorf("connection %q is not connected", job.Connection)
}
jobConnStatus := GetJobConnStatus(jobId)
if jobConnStatus != JobConnStatus_Connected {
return nil, fmt.Errorf("job is not connected (status: %s)", jobConnStatus)
}
return job, nil
}
type StartJobParams struct {
ConnName string
JobKind string
Cmd string
Args []string
Env map[string]string
TermSize *waveobj.TermSize
BlockId string
}
func StartJob(ctx context.Context, params StartJobParams) (string, error) {
if params.ConnName == "" {
return "", fmt.Errorf("connection name is required")View on GitHub (pinned to a4447c1563)
Solutions
- Wait briefly and retry until job status becomes Connected
- Restart the job if its status is terminally degraded
- Check logs for the remote job's exit reason
- Serialize SendInput behind a connected-state gate instead of calling directly
Example fix
// before
_, err := jobcontroller.CheckJobConnected(ctx, jobId)
if err != nil {
return err
}
// after
err := waitForCondition(func() bool {
_, err := jobcontroller.CheckJobConnected(ctx, jobId)
return err == nil
}, 5*time.Second)
if err != nil {
return fmt.Errorf("job %s never became connected: %w", jobId, err)
} Defensive patterns
Strategy: retry
Validate before calling
if jobcontroller.GetJobConnStatus(jobId) != jobcontroller.JobConnStatus_Connected {
return fmt.Errorf("job %s not ready for input", jobId)
} Type guard
func isJobStatusMismatchErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "job is not connected (status:")
} Try / catch
_, err := jobcontroller.CheckJobConnected(ctx, jobId)
if isJobStatusMismatchErr(err) {
time.Sleep(250 * time.Millisecond)
_, err = jobcontroller.CheckJobConnected(ctx, jobId)
}
if err != nil { return err } Prevention
- After StartJob, wait for Connected status before sending input
- Poll job status with a bounded retry window
- Restart the job if it stays non-Connected
- Watch for status transitions on reconnect races
When it happens
Trigger: Calling CheckJobConnected when GetJobConnStatus returns any status other than Connected — job starting up, job torn down on the remote side, or stale job-status map entry after a reconnect.
Common situations: Sending input immediately after StartJob before the job's connection handshake finishes; remote shell exited and the status degraded; reconnect race where conn is up but the job is not yet reattached.
Related errors
- window ${windowId} not found
- encryption is not available
- wsl connection %s not connected, cannot start shellproc
- ssh connection not found: %s
- ssh connection %s not connected, cannot start shellproc
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/f8a43ee9e7a5f0ed.
Report an issue: GitHub.