wavetermdev/waveterm · error

invalid pgid returned: %d

Error message

invalid pgid returned: %d

What it means

After a successful GetProcessGroupId call, GetPGID sanity-checks that the returned pgid is positive. A zero or negative value would be nonsensical, so it is rejected with this error — indicating an unexpected kernel/utility-layer response.

Source

Thrown at pkg/jobmanager/jobcmd.go:132

	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 {
		return false, nil
	}
	exitData := &wshrpc.CommandJobCmdExitedData{
		JobId:      WshCmdJobManager.JobId,
		ExitCode:   jm.exitCode,
		ExitSignal: jm.exitSignal,
		ExitTs:     jm.exitTs,
	}
	if jm.exitErr != nil {
		exitData.ExitErr = jm.exitErr.Error()

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the unixutil.GetProcessGroupId implementation for the current platform and fix the return-value handling.
  2. Log the pid/pgid pair and report a bug if a real kernel returned pgid <= 0.
  3. Fall back to treating the process's pid as its group leader when the lookup misbehaves.
  4. Add a unit test asserting positive pgid on each supported platform.

Example fix

// before
pgid, err := unixutil.GetProcessGroupId(pid)
return pgid, err
// after
pgid, err := unixutil.GetProcessGroupId(pid)
if pgid <= 0 {
    return 0, fmt.Errorf("invalid pgid returned: %d", pgid)
}
return pgid, err
Defensive patterns

Strategy: type-guard

Validate before calling

func sanePGID(pgid int) bool { return pgid > 0 }

Type guard

func isValidPGID(pgid int, ok bool) bool {
    return ok && pgid > 0
}

Try / catch

pgid, err := jobCmd.GetPGID()
if err != nil {
    if strings.Contains(err.Error(), "invalid pgid returned") {
        // platform bug: fall back to treating pid as pgid
        return jobCmd.PID()
    }
    return err
}

Prevention

When it happens

Trigger: unixutil.GetProcessGroupId returns a non-positive value despite reporting success — essentially only from a broken platform implementation or an unexpected syscall result.

Common situations: Porting to a new OS/platform where the pgid lookup shim returns 0 on success; a stubbed or mocked unixutil in tests.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/a6832b172fc34af8. Report an issue: GitHub.