{"record":{"id":"1df8bc55c4cae2be","repo":"wavetermdev/waveterm","slug":"failed-to-start-job-w-1df8bc","errorCode":null,"errorMessage":"failed to start job: %w","messagePattern":"failed to start job: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshremote/wshremote_job.go","lineNumber":274,"sourceCode":"\n\tcombinedEnv := make(map[string]string)\n\tfor k, v := range impl.InitialEnv {\n\t\tcombinedEnv[k] = v\n\t}\n\tfor k, v := range data.Env {\n\t\tcombinedEnv[k] = v\n\t}\n\tstartJobData := wshrpc.CommandStartJobData{\n\t\tCmd:        data.Cmd,\n\t\tArgs:       data.Args,\n\t\tEnv:        combinedEnv,\n\t\tTermSize:   data.TermSize,\n\t\tStreamMeta: data.StreamMeta,\n\t}\n\trtnData, err := wshclient.StartJobCommand(impl.RpcClient, startJobData, &wshrpc.RpcOpts{Route: jobRouteId})\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, fmt.Errorf(\"failed to start job: %w\", err)\n\t}\n\n\treturn rtnData, nil\n}\n\nfunc (impl *ServerImpl) RemoteReconnectToJobManagerCommand(ctx context.Context, data wshrpc.CommandRemoteReconnectToJobManagerData) (*wshrpc.CommandRemoteReconnectToJobManagerRtnData, error) {\n\tlog.Printf(\"RemoteReconnectToJobManagerCommand: reconnecting, jobid=%s\\n\", data.JobId)\n\tif impl.Router == nil {\n\t\treturn &wshrpc.CommandRemoteReconnectToJobManagerRtnData{\n\t\t\tSuccess: false,\n\t\t\tError:   \"cannot reconnect to job manager: no router available\",\n\t\t}, nil\n\t}\n\n\tproc, err := isProcessRunning(data.JobManagerPid, data.JobManagerStartTs)\n\tif err != nil {\n\t\treturn &wshrpc.CommandRemoteReconnectToJobManagerRtnData{\n\t\t\tSuccess: false,","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshremote/wshremote_job.go#L256-L292","documentation":"RemoteStartJobCommand launches a streaming job (e.g. remote command stream) on the client side: it builds start-job data and calls StartJobCommand over RPC routed to the remote job manager. This error wraps any failure returned by that RPC when the remote side refuses or fails to start the job, after running cleanup of locally-created resources. It means the job never started and the wrapped cause is the remote's start error.","triggerScenarios":"Calling RemoteStartJobCommand where the routed jobRouteId peer rejects the start: invalid/unknown route (no job manager there), remote side failed to spawn the job, protocol/route mismatch after reconnect, or the RPC times out / connection drops during StartJobCommand.","commonSituations":"Job manager process died or was killed between job-manager creation and StartJobCommand; connecting over a flaky SSH connection; wave version mismatch where the remote does not support the requested stream/job protocol; stale jobRouteId cached from a previous session.","solutions":["Inspect the wrapped cause (%w) in the error chain to see the underlying RPC failure (route-not-found, remote spawn error, timeout).","Verify the job manager is alive on the remote (RemoteReconnectToJobManagerCommand or isProcessRunning) and reconnect if stale.","Retry RemoteStartJobCommand after the connection is re-established.","Ensure wsh versions match on both ends; upgrade wsh on the remote host."],"exampleFix":"// before\nrtnData, err := wshclient.StartJobCommand(impl.RpcClient, startJobData, &wshrpc.RpcOpts{Route: jobRouteId})\nif err != nil {\n    return nil, fmt.Errorf(\"failed to start job: %w\", err)\n}\n// after\nrtnData, err := wshclient.StartJobCommand(impl.RpcClient, startJobData, &wshrpc.RpcOpts{Route: jobRouteId})\nif err != nil {\n    if errors.Is(err, wshutil.ErrRouteNotFound) {\n        jobRouteId = reestablishJobManager(ctx) // reconnect then retry\n    }\n    return nil, fmt.Errorf(\"failed to start job: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// before calling RemoteStartJobCommand\nif !connController.IsConnected(routeId) {\n    return errors.New(\"job route not connected; reconnect first\")\n}","typeGuard":"func isRouteNotFound(err error) bool {\n    return err != nil && (errors.Is(err, wshutil.ErrRouteNotFound) || strings.Contains(err.Error(), \"route not found\"))\n}","tryCatchPattern":"rtnData, err := wshclient.StartJobCommand(...)\nif err != nil {\n    var rpcErr *wshrpc.RpcError\n    if errors.As(err, &rpcErr) && isRouteNotFound(err) {\n        // reconnect job manager and retry once\n    }\n    return fmt.Errorf(\"failed to start job: %w\", err)\n}","preventionTips":["Always check connection state to the job route before starting a job","Keep wsh versions in sync between local and remote","Unwrap and log the %w cause chain to classify failures","Clean up route subscriptions on failure (the impl already runs cleanup())"],"tags":["rpc","remote-execution","job-manager"],"backgroundTag":"rpc-route-failure","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}