wavetermdev/waveterm · error
no active process
Error message
no active process
What it means
GetPGID requires a live OS process handle on the job's command. If jm.cmd or jm.cmd.Process is nil, no process was ever started (or the handle was never populated), so the lookup cannot proceed and this error is returned.
Source
Thrown at pkg/jobmanager/jobcmd.go:122
if jm.exitCode != nil {
exitCodeStr = fmt.Sprintf("%d", *jm.exitCode)
}
log.Printf("process exited: exitcode=%s, signal=%s, err=%v\n", exitCodeStr, jm.exitSignal, jm.exitErr)
go WshCmdJobManager.sendJobExited()
}
func (jm *JobCmd) GetCmd() (*exec.Cmd, pty.Pty) {
jm.lock.Lock()
defer jm.lock.Unlock()
return jm.cmd, jm.cmdPty
}
func (jm *JobCmd) GetPGID() (int, error) {
jm.lock.Lock()
defer jm.lock.Unlock()
if jm.cmd == nil || jm.cmd.Process == nil {
return 0, fmt.Errorf("no active process")
}
if jm.processExited {
return 0, fmt.Errorf("process already exited")
}
pgid, err := unixutil.GetProcessGroupId(jm.cmd.Process.Pid)
if err != nil {
return 0, fmt.Errorf("failed to get pgid: %w", err)
}
if pgid <= 0 {
return 0, fmt.Errorf("invalid pgid returned: %d", pgid)
}
return pgid, nil
}
func (jm *JobCmd) GetExitInfo() (bool, *wshrpc.CommandJobCmdExitedData) {
jm.lock.Lock()
defer jm.lock.Unlock()
if !jm.processExited {View on GitHub (pinned to a4447c1563)
Solutions
- Only call GetPGID after StartJob reports success.
- Check the job's running/exited status before querying the pgid.
- Guard the call site: skip pgid lookup when the job was never started.
- Recreate/restart the job if the handle was lost.
Example fix
// before
pgid, err := jobCmd.GetPGID()
// after
if !jobMgr.IsRunning() {
return 0, errors.New("job not started")
}
pgid, err := jobCmd.GetPGID() Defensive patterns
Strategy: validation
Validate before calling
// ensure the job was started successfully before querying pgid
if !jobStartedSuccessfully { // track via StartJob result
return errors.New("cannot get pgid: job never started")
} Type guard
func jobQueryable(jm *jobmanager.JobCmd) bool {
_, err := jm.GetExitInfo()
return err == nil // job object is live and queryable
} Try / catch
pgid, err := jobCmd.GetPGID()
if err != nil {
if err.Error() == "no active process" {
return 0, errors.New("job was never started; call StartJob first")
}
return 0, err
} Prevention
- Only call GetPGID after StartJob returns success
- Sequence process-management RPCs after the job-start confirmation event
- Never reuse a JobCmd across start failures
When it happens
Trigger: Calling GetPGID on a JobCmd before StartJob/MakeJobCmd succeeded, or after the command struct exists but pty.StartWithSize failed so jm.cmd.Process was never set.
Common situations: A client querying the process group of a job that failed to launch; a race where GetPGID is called between JobCmd creation and successful start; job object restored from state without a live process.
Related errors
- process already exited
- failed to get pgid: %w
- Layout model not found
- Display container not found
- procinfo: process not found
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/65ba4bbd000a13a9.
Report an issue: GitHub.