wavetermdev/waveterm · error
error checking job manager process: %w
Error message
error checking job manager process: %w
What it means
RemoteTerminateJobManagerCommand checks whether the remote job manager process is still running (via isProcessRunning comparing pid and start timestamp) before sending SIGTERM. This error wraps a failure of that check itself — i.e. the code could not determine the process state (OS-level lookup error), so termination is aborted. It does not mean the process is running or not; the state is unknown.
Source
Thrown at pkg/wshrpc/wshremote/wshremote_job.go:346
conn := impl.getJobManagerConnection(data.JobId)
if conn == nil {
log.Printf("RemoteDisconnectFromJobManagerCommand: no connection found for jobid=%s\n", data.JobId)
return nil
}
if conn.CleanupFn != nil {
conn.CleanupFn()
log.Printf("RemoteDisconnectFromJobManagerCommand: cleanup completed for jobid=%s\n", data.JobId)
}
return nil
}
func (impl *ServerImpl) RemoteTerminateJobManagerCommand(ctx context.Context, data wshrpc.CommandRemoteTerminateJobManagerData) error {
log.Printf("RemoteTerminateJobManagerCommand: terminating job manager, jobid=%s, pid=%d\n", data.JobId, data.JobManagerPid)
proc, err := isProcessRunning(data.JobManagerPid, data.JobManagerStartTs)
if err != nil {
return fmt.Errorf("error checking job manager process: %w", err)
}
if proc == nil {
log.Printf("RemoteTerminateJobManagerCommand: job manager process not running, jobid=%s\n", data.JobId)
return nil
}
err = proc.SendSignal(syscall.SIGTERM)
if err != nil {
log.Printf("failed to send SIGTERM to job manager: %v", err)
} else {
log.Printf("RemoteTerminateJobManagerCommand: sent SIGTERM to job manager process, jobid=%s, pid=%d\n", data.JobId, data.JobManagerPid)
}
return nil
}
View on GitHub (pinned to a4447c1563)
Solutions
- Check the wrapped cause for an OS/permission error (e.g. EPERM reading process info).
- Retry as the same user that started the job manager, or run with sufficient privileges.
- Treat as best-effort: proceed to kill by pid or clean up job state on the next reconnect if SIGTERM cannot be attempted.
- Verify the remote platform supports the isProcessRunning implementation used by wsh.
Example fix
// before
proc, err := isProcessRunning(data.JobManagerPid, data.JobManagerStartTs)
if err != nil {
return fmt.Errorf("error checking job manager process: %w", err)
}
// after
proc, err := isProcessRunning(data.JobManagerPid, data.JobManagerStartTs)
if err != nil {
log.Printf("process check failed (%v), attempting best-effort signal", err)
proc = nil // or fall through to a direct kill by pid
} Defensive patterns
Strategy: try-catch
Type guard
func isProcessCheckError(err error) bool {
return err != nil && !errors.Is(err, os.ErrNotExist)
} Try / catch
if err := wshclient.RemoteTerminateJobManagerCommand(ctx, data, nil); err != nil {
if isProcessCheckError(err) {
// fall back to best-effort cleanup: mark job manager state unknown
log.Printf("could not verify job manager pid %d: %v", data.JobManagerPid, err)
}
} Prevention
- Start the job manager as the same user that will terminate it
- Handle EPERM/EACCES from process inspection gracefully
- Treat process-state checks as best-effort in containers/restricted environments
- Persist JobManagerStartTs correctly so stale-pid collisions are detected
When it happens
Trigger: isProcessRunning fails: OS error reading /proc (Linux) or equivalent for the given pid, permission denied inspecting another user's process, or the process-table lookup API returning an unexpected error.
Common situations: Job manager ran as a different user so its process info is unreadable; container/restricted environment where /proc is limited; stale pid that collides with a protected system process; platform differences (macOS vs Linux ps semantics).
Related errors
- failed to start job: %w
- procinfo: process not found
- error starting controller: %w
- failed to start durable shell: %w
- failed to run tsunami app: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/8ef4c6ae8987fe28.
Report an issue: GitHub.