wavetermdev/waveterm · error
error getting job manager status: %w
Error message
error getting job manager status: %w
What it means
If the block already has a JobId, Start queries jobcontroller.GetJobManagerStatus to see whether that job's manager is still running. This error wraps a failure of that status query (job record missing, RPC to remote failed, etc.).
Source
Thrown at pkg/blockcontroller/durableshellcontroller.go:153
// - force=true: detaches old job and starts new one
// - force=false: returns without starting (leaves block unstarted)
//
// After establishing jobId, ensures job connection is active (reconnects if needed)
func (dsc *DurableShellController) Start(ctx context.Context, blockMeta waveobj.MetaMapType, rtOpts *waveobj.RuntimeOpts, force bool) error {
blockData, err := wstore.DBMustGet[*waveobj.Block](ctx, dsc.BlockId)
if err != nil {
return fmt.Errorf("error getting block: %w", err)
}
if conncontroller.IsLocalConnName(dsc.ConnName) {
return fmt.Errorf("durable shell controller requires a remote connection")
}
var jobId string
if blockData.JobId != "" {
status, err := jobcontroller.GetJobManagerStatus(ctx, blockData.JobId)
if err != nil {
return fmt.Errorf("error getting job manager status: %w", err)
}
if status == jobcontroller.JobManagerStatus_Running {
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)
}View on GitHub (pinned to a4447c1563)
Solutions
- Retry Start once the connection is healthy
- Clear the stale blockData.JobId so Start creates a fresh job (startNewJob path)
- Verify the remote host is reachable and the job store is intact
- If the job is truly gone, treat this as recoverable and restart the shell
Example fix
// before
status, err := jobcontroller.GetJobManagerStatus(ctx, jobId)
if err != nil { return err }
// after (caller-side recovery)
if err := dsc.Start(ctx, meta, rtOpts, true); err != nil && strings.Contains(err.Error(), "job manager status") {
// clear stale jobId in block meta and retry to start a new job
} Defensive patterns
Strategy: retry
Try / catch
if err := dsc.Start(ctx, meta, rtOpts, true); err != nil && strings.Contains(err.Error(), "job manager status") {
// clear stale blockData.JobId and retry Start to create a fresh job
} Prevention
- Clean up dangling JobIds when the remote restarts
- Ensure connection is connected before status checks
- Treat job status errors as recoverable, not fatal
When it happens
Trigger: blockData.JobId is set but GetJobManagerStatus errors — e.g. the job record was pruned, the remote connection can't be reached to check the job, or the job manager returned an error.
Common situations: Dangling JobId from a previous session whose job records were cleaned up; remote host rebooted losing job state; connection flaky at status-check time.
Related errors
- failed to start new job: %w
- failed to reconnect to job: %w
- starting file stream: %w
- not connected: %s
- error getting block: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/561448fef2e28634.
Report an issue: GitHub.