google/zx · error · Fail

Invalid pid: ${pid}

Error message

Invalid pid: ${pid}

What it means

Thrown by the module-level kill(pid, signal) function when pid is not a non-negative integer. The guard accepts a number or a string of digits (matching /^\d+$/); anything else (undefined, NaN, negative number, 'abc', an object, a float) is rejected before any signal is sent.

Source

Thrown at src/core.ts:1065

export function cd(dir: string | ProcessOutput) {
  if (dir instanceof ProcessOutput) {
    dir = dir.toString().trim()
  }

  $.log({ kind: 'cd', dir, verbose: !$.quiet && $.verbose })
  process.chdir(dir)
  $[CWD] = process.cwd()
}

export async function kill(
  pid: number | `${number}`,
  signal = $.killSignal || SIGTERM
) {
  if (
    (typeof pid !== 'number' && typeof pid !== 'string') ||
    !/^\d+$/.test(pid as string)
  )
    throw new Fail(`Invalid pid: ${pid}`)

  $.log({ kind: 'kill', pid, signal, verbose: !$.quiet && $.verbose })
  if (
    process.platform === 'win32' &&
    (await new Promise((resolve) => {
      cp.exec(`taskkill /pid ${pid} /t /f`, (err) => resolve(!err))
    }))
  )
    return

  for (const p of await ps.tree({ pid, recursive: true })) {
    try {
      process.kill(+p.pid, signal)
    } catch (e) {}
  }
  try {
    process.kill(-pid, signal)
  } catch (e) {

View on GitHub (pinned to 00a2c484e2)

Solutions

  1. Validate before calling: `if (/^\d+$/.test(String(pid))) kill(+pid)`.
  2. Check the source of the pid (env var, config, process object) and default/handle missing values.
  3. For zx-spawned commands, use the instance method pp.kill() instead of the module-level kill().

Example fix

// before
kill(maybePid)
// after
if (typeof maybePid === 'number' && maybePid >= 0) kill(maybePid)
Defensive patterns

Strategy: validation

Validate before calling

function isPid(v: unknown): v is number | `${number}` {
  return (typeof v === 'number' || typeof v === 'string') && /^\d+$/.test(String(v))
}

if (!isPid(pid)) throw new TypeError(`Invalid pid: ${String(pid)}`)
kill(pid as number)

Type guard

const isNumericPid = (v: unknown): v is number | `${number}` =>
  typeof v === 'number' ? Number.isInteger(v) && v >= 0 : /^\d+$/.test(String(v))

Try / catch

try {
  await kill(pid as any)
} catch (e) {
  if (e instanceof Fail && /Invalid pid/.test(e.message)) {
    console.error('pid was not a non-negative integer:', pid)
  } else throw e
}

Prevention

When it happens

Trigger: `kill(undefined)`; `kill(NaN)`; `kill('abc')`; `kill(-1)`; `kill(someObject)`; passing a pid read from a missing env var or JSON field; passing a process object instead of its .pid.

Common situations: Reading a pid from env/JSON that is absent; parseFloat on bad input yielding NaN; passing `child` instead of `child.pid`; negative pids from miscomputed values.

Related errors


AI-assisted analysis of google/zx@00a2c484e2 (2026-08-13). Data as JSON: /api/errors/a0c994ccd1767a79. Report an issue: GitHub.