wavetermdev/waveterm · error
failed to start new job: %w
Error message
failed to start new job: %w
What it means
After provisioning the term file, Start launches the durable shell via dsc.startNewJob. This error wraps any failure from that call — job creation, connection/RPC to the remote, or command launch failure — so the shell never gets a jobId.
Source
Thrown at pkg/blockcontroller/durableshellcontroller.go:174
jobId = blockData.JobId
} else if !force {
log.Printf("block %q has jobId %s but manager is not running (status: %s), not starting (force=false)\n", dsc.BlockId, blockData.JobId, status)
return nil
} else {
log.Printf("block %q has jobId %s but manager is not running (status: %s), starting new job (force=true)\n", dsc.BlockId, blockData.JobId, status)
// intentionally leave jobId empty to trigger starting a new job below
}
}
if jobId == "" {
log.Printf("block %q starting new durable shell\n", dsc.BlockId)
fsErr := filestore.WFS.MakeFile(ctx, dsc.BlockId, wavebase.BlockFile_Term, nil, wshrpc.FileOpts{MaxSize: DefaultTermMaxFileSize, Circular: true})
if fsErr != nil && fsErr != fs.ErrExist {
return fmt.Errorf("error creating block term file: %w", fsErr)
}
newJobId, err := dsc.startNewJob(ctx, blockMeta, dsc.ConnName, rtOpts)
if err != nil {
return fmt.Errorf("failed to start new job: %w", err)
}
jobId = newJobId
}
dsc.WithLock(func() {
dsc.JobId = jobId
dsc.sendUpdate_withlock()
})
err = jobcontroller.ReconnectJob(ctx, jobId, rtOpts)
if err != nil {
return fmt.Errorf("failed to reconnect to job: %w", err)
}
return nil
}
func (dsc *DurableShellController) Stop(graceful bool, newStatus string, destroy bool) {View on GitHub (pinned to a4447c1563)
Solutions
- Reconnect the remote connection and retry Start
- Check block runtime options (shell type, args) are valid for the remote host
- Look at connection logs for the underlying startNewJob failure
- Update wave on the remote host if version mismatch is suspected
Example fix
// before
err := dsc.Start(ctx, meta, rtOpts, true)
// after
if err := dsc.Start(ctx, meta, rtOpts, true); err != nil {
if isConnErr(err) {
time.Sleep(3 * time.Second)
err = dsc.Start(ctx, meta, rtOpts, true) // retry after reconnect
}
} Defensive patterns
Strategy: retry
Validate before calling
if c := conncontroller.MaybeGetConn(opts); c == nil || c.DeriveConnStatus().Status != conncontroller.Status_Connected {
return errors.New("connect remote before starting durable shell")
} Try / catch
if err := dsc.Start(ctx, meta, rtOpts, true); err != nil && strings.Contains(err.Error(), "failed to start new job") {
// reconnect, verify shell opts, retry with backoff
} Prevention
- Verify the remote connection is Connected before launching durable shells
- Validate block runtime opts (shell type/args) per host
- Keep wave versions in sync between client and remote hosts
When it happens
Trigger: startNewJob fails: connection to the remote is down or drops during launch, the remote job controller rejects the start, shell command invalid (bad rtOpts/shell type), or auth fails mid-launch.
Common situations: SSH connection unstable right when the terminal starts; invalid shell type in block runtime options; remote host refusing new sessions (MaxSessions, out of memory); wave client on the remote outdated.
Related errors
- error getting job manager status: %w
- failed to reconnect to job: %w
- connection %q not found
- watching pid: %v
- cannot parse connection name: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/e55c96fe624fa8e6.
Report an issue: GitHub.