abhigyanpatwari/GitNexus · error · ValueError

PID-namespace command must not be empty

Error message

PID-namespace command must not be empty

What it means

Raised as a ValueError (not SandboxError) by pid_namespace_command when the command sequence is empty. The function builds a bwrap invocation prefixed around the supplied argv; an empty argv would exec bwrap with no command, which is undefined, so the guard rejects it up front. Callers catching SandboxError alone will miss this — it is a ValueError.

Source

Thrown at eval/workflow_bench/proposer_sandbox.py:515

    if not result.ok:
        raise SandboxError(f"Bubblewrap namespace preflight failed: {result.detail or result.stderr_tail[-1000:]}")
    return bwrap


def pid_namespace_command(
    command: Sequence[str],
    *,
    bwrap_bin: Path,
) -> list[str]:
    """Wrap a trusted host command in an owned PID namespace.

    This boundary deliberately preserves the host filesystem and network; its
    sole purpose is making every descendant visible to the outer driver even
    when a nested command creates a new session or process group.
    """

    if not command:
        raise ValueError("PID-namespace command must not be empty")
    return [
        str(bwrap_bin),
        "--unshare-user",
        "--unshare-pid",
        "--unshare-ipc",
        "--unshare-uts",
        "--die-with-parent",
        "--new-session",
        "--bind",
        "/",
        "/",
        "--proc",
        "/proc",
        "--dev",
        "/dev",
        "--",
        *command,
    ]

View on GitHub (pinned to d540b00184)

Solutions

  1. Ensure the command sequence has at least one element (the program) before calling: assert command, 'command required'.
  2. Default to an explicit program (e.g. ['/usr/bin/true']) when the dynamic argv is empty rather than calling pid_namespace_command at all.
  3. Fix the upstream argv construction so an empty case is handled before this boundary.
  4. Catch ValueError in addition to SandboxError if this path can be reached from user input.

Example fix

// before
wrapped = pid_namespace_command(cmd, bwrap_bin=bwrap)  # cmd may be []
// after
if not cmd:
    raise ValueError('cannot wrap an empty command')
wrapped = pid_namespace_command(cmd, bwrap_bin=bwrap)
Defensive patterns

Strategy: validation

Validate before calling

def wrap_pid_namespace(command, bwrap_bin):
    if not command:
        raise ValueError('cannot wrap an empty command')
    return pid_namespace_command(command, bwrap_bin=bwrap_bin)

Type guard

from collections.abc import Sequence

def is_non_empty_command(value: object) -> bool:
    return isinstance(value, (list, tuple)) and len(value) > 0 and all(isinstance(p, str) for p in value)

Try / catch

try:
    wrapped = pid_namespace_command(command, bwrap_bin=bwrap)
except ValueError as exc:
    if 'must not be empty' in str(exc):
        raise SystemExit('refusing to wrap an empty command')
    raise

Prevention

When it happens

Trigger: Calling pid_namespace_command([], bwrap_bin=...) — passing an empty list/tuple as the command argument.

Common situations: Caller built argv from optional flags and produced [] when all were absent; a list comprehension over an empty input yielded an empty command; a refactor passed the wrong variable (e.g. args instead of args.command); a test fixture constructed command=[].

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/01cc86ec7ce7c37e. Report an issue: GitHub.