wavetermdev/waveterm · error

failed to start job: %w

Error message

failed to start job: %w

What it means

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.

Source

Thrown at pkg/wshrpc/wshremote/wshremote_job.go:274

	combinedEnv := make(map[string]string)
	for k, v := range impl.InitialEnv {
		combinedEnv[k] = v
	}
	for k, v := range data.Env {
		combinedEnv[k] = v
	}
	startJobData := wshrpc.CommandStartJobData{
		Cmd:        data.Cmd,
		Args:       data.Args,
		Env:        combinedEnv,
		TermSize:   data.TermSize,
		StreamMeta: data.StreamMeta,
	}
	rtnData, err := wshclient.StartJobCommand(impl.RpcClient, startJobData, &wshrpc.RpcOpts{Route: jobRouteId})
	if err != nil {
		cleanup()
		return nil, fmt.Errorf("failed to start job: %w", err)
	}

	return rtnData, nil
}

func (impl *ServerImpl) RemoteReconnectToJobManagerCommand(ctx context.Context, data wshrpc.CommandRemoteReconnectToJobManagerData) (*wshrpc.CommandRemoteReconnectToJobManagerRtnData, error) {
	log.Printf("RemoteReconnectToJobManagerCommand: reconnecting, jobid=%s\n", data.JobId)
	if impl.Router == nil {
		return &wshrpc.CommandRemoteReconnectToJobManagerRtnData{
			Success: false,
			Error:   "cannot reconnect to job manager: no router available",
		}, nil
	}

	proc, err := isProcessRunning(data.JobManagerPid, data.JobManagerStartTs)
	if err != nil {
		return &wshrpc.CommandRemoteReconnectToJobManagerRtnData{
			Success: false,

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the wrapped cause (%w) in the error chain to see the underlying RPC failure (route-not-found, remote spawn error, timeout).
  2. Verify the job manager is alive on the remote (RemoteReconnectToJobManagerCommand or isProcessRunning) and reconnect if stale.
  3. Retry RemoteStartJobCommand after the connection is re-established.
  4. Ensure wsh versions match on both ends; upgrade wsh on the remote host.

Example fix

// before
rtnData, err := wshclient.StartJobCommand(impl.RpcClient, startJobData, &wshrpc.RpcOpts{Route: jobRouteId})
if err != nil {
    return nil, fmt.Errorf("failed to start job: %w", err)
}
// after
rtnData, err := wshclient.StartJobCommand(impl.RpcClient, startJobData, &wshrpc.RpcOpts{Route: jobRouteId})
if err != nil {
    if errors.Is(err, wshutil.ErrRouteNotFound) {
        jobRouteId = reestablishJobManager(ctx) // reconnect then retry
    }
    return nil, fmt.Errorf("failed to start job: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// before calling RemoteStartJobCommand
if !connController.IsConnected(routeId) {
    return errors.New("job route not connected; reconnect first")
}

Type guard

func isRouteNotFound(err error) bool {
    return err != nil && (errors.Is(err, wshutil.ErrRouteNotFound) || strings.Contains(err.Error(), "route not found"))
}

Try / catch

rtnData, err := wshclient.StartJobCommand(...)
if err != nil {
    var rpcErr *wshrpc.RpcError
    if errors.As(err, &rpcErr) && isRouteNotFound(err) {
        // reconnect job manager and retry once
    }
    return fmt.Errorf("failed to start job: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/1df8bc55c4cae2be. Report an issue: GitHub.