wavetermdev/waveterm · error
failed to start durable shell: %w
Error message
failed to start durable shell: %w
What it means
This is the final wrapper around shellexec.StartRemoteShellJob, which actually spawns the durable remote shell job over the connection. Any failure launching that job (SSH exec failure, remote command error, job setup failure) is surfaced with this message. The durable shell was not created and no JobId is returned.
Source
Thrown at pkg/blockcontroller/durableshellcontroller.go:274
BlockId: dsc.BlockId,
Conn: connName,
}
jwtStr, err := wshutil.MakeClientJWTToken(rpcContext)
if err != nil {
return "", fmt.Errorf("error making jwt token: %w", err)
}
swapToken.RpcContext = &rpcContext
swapToken.Env[wshutil.WaveJwtTokenVarName] = jwtStr
cmdOpts := shellexec.CommandOptsType{
Interactive: true,
Login: true,
Cwd: cwd,
SwapToken: swapToken,
ForceJwt: blockMeta.GetBool(waveobj.MetaKey_CmdJwt, false),
}
jobId, err := shellexec.StartRemoteShellJob(ctx, ctx, termSize, cmdStr, cmdOpts, conn, dsc.BlockId)
if err != nil {
return "", fmt.Errorf("failed to start durable shell: %w", err)
}
return jobId, nil
}
View on GitHub (pinned to a4447c1563)
Solutions
- Read the wrapped inner error for the precise remote-side failure.
- Test the same shell command over plain ssh (ssh host -t 'bash -l').
- Check the remote account's shell and authorized_keys for forced commands restricting exec.
- Verify the cmd/cmd-cwd meta values exist on the remote.
- Retry after fixing remote capacity issues (disk, sessions, permissions).
Example fix
// before
meta := waveobj.MetaMapType{"cmd": "/usr/local/bin/zsh", "conn": "server"} // zsh not installed remotely
// after
meta := waveobj.MetaMapType{"cmd": "/bin/bash", "conn": "server"} // shell that exists on the remote Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check meta before Start
if cmd := blockMeta.GetString(waveobj.MetaKey_Cmd, ""); cmd != "" {
// ensure cmd exists remotely via a probe command if possible
}
if conn.DeriveConnStatus().Status != conncontroller.Status_Connected {
return fmt.Errorf("remote not connected")
} Try / catch
if err := controller.Start(ctx, meta, rtOpts, false); err != nil {
var inner error
errors.As(err, &inner) // unwrap 'failed to start durable shell' cause
log.Printf("durable shell start failed: %v", inner)
return err
} Prevention
- Verify the remote account's login shell and authorized_keys are not restricted
- Test the cmd value over plain ssh first
- Keep remote disks/permissions healthy
- Match wsh versions between client and remote
When it happens
Trigger: StartRemoteShellJob fails: the SSH channel cannot open, the remote shell command (cmdStr) fails, term/command options are invalid, or the remote refuses the interactive shell session.
Common situations: Remote user's default shell is invalid or restricted (rbash, nologin); server rejects interactive/login shells (MaxSessions, forced command in authorized_keys); disk-full or permission errors on the remote; cmd meta specifies a binary not present remotely.
Related errors
- failed to start process: %w
- cannot start shellproc: %w
- failed to reconnect to job: %w
- invalid ssh remote name (%s): %w
- connection %q not found
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/9d0a9c55af74f97d.
Report an issue: GitHub.