{"record":{"id":"561448fef2e28634","repo":"wavetermdev/waveterm","slug":"error-getting-job-manager-status-w","errorCode":null,"errorMessage":"error getting job manager status: %w","messagePattern":"error getting job manager status: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/blockcontroller/durableshellcontroller.go","lineNumber":153,"sourceCode":"//   - force=true: detaches old job and starts new one\n//   - force=false: returns without starting (leaves block unstarted)\n//\n// After establishing jobId, ensures job connection is active (reconnects if needed)\nfunc (dsc *DurableShellController) Start(ctx context.Context, blockMeta waveobj.MetaMapType, rtOpts *waveobj.RuntimeOpts, force bool) error {\n\tblockData, err := wstore.DBMustGet[*waveobj.Block](ctx, dsc.BlockId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting block: %w\", err)\n\t}\n\n\tif conncontroller.IsLocalConnName(dsc.ConnName) {\n\t\treturn fmt.Errorf(\"durable shell controller requires a remote connection\")\n\t}\n\n\tvar jobId string\n\tif blockData.JobId != \"\" {\n\t\tstatus, err := jobcontroller.GetJobManagerStatus(ctx, blockData.JobId)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error getting job manager status: %w\", err)\n\t\t}\n\t\tif status == jobcontroller.JobManagerStatus_Running {\n\t\t\tjobId = blockData.JobId\n\t\t} else if !force {\n\t\t\tlog.Printf(\"block %q has jobId %s but manager is not running (status: %s), not starting (force=false)\\n\", dsc.BlockId, blockData.JobId, status)\n\t\t\treturn nil\n\t\t} else {\n\t\t\tlog.Printf(\"block %q has jobId %s but manager is not running (status: %s), starting new job (force=true)\\n\", dsc.BlockId, blockData.JobId, status)\n\t\t\t// intentionally leave jobId empty to trigger starting a new job below\n\t\t}\n\t}\n\n\tif jobId == \"\" {\n\t\tlog.Printf(\"block %q starting new durable shell\\n\", dsc.BlockId)\n\t\tfsErr := filestore.WFS.MakeFile(ctx, dsc.BlockId, wavebase.BlockFile_Term, nil, wshrpc.FileOpts{MaxSize: DefaultTermMaxFileSize, Circular: true})\n\t\tif fsErr != nil && fsErr != fs.ErrExist {\n\t\t\treturn fmt.Errorf(\"error creating block term file: %w\", fsErr)\n\t\t}","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/blockcontroller/durableshellcontroller.go#L135-L171","documentation":"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.).","triggerScenarios":"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.","commonSituations":"Dangling JobId from a previous session whose job records were cleaned up; remote host rebooted losing job state; connection flaky at status-check time.","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"],"exampleFix":"// before\nstatus, err := jobcontroller.GetJobManagerStatus(ctx, jobId)\nif err != nil { return err }\n// after (caller-side recovery)\nif err := dsc.Start(ctx, meta, rtOpts, true); err != nil && strings.Contains(err.Error(), \"job manager status\") {\n    // clear stale jobId in block meta and retry to start a new job\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := dsc.Start(ctx, meta, rtOpts, true); err != nil && strings.Contains(err.Error(), \"job manager status\") {\n    // clear stale blockData.JobId and retry Start to create a fresh job\n}","preventionTips":["Clean up dangling JobIds when the remote restarts","Ensure connection is connected before status checks","Treat job status errors as recoverable, not fatal"],"tags":["job","durable-shell","remote","status"],"backgroundTag":"job-status-check-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}