abhigyanpatwari/GitNexus · error · ValueError

capture_stdout_bytes must be positive when supplied

Error message

capture_stdout_bytes must be positive when supplied

What it means

Companion validator in _run_managed_inner: when capture_stdout_bytes is supplied (not None) it must be strictly positive, because a zero-byte bounded capture is meaningless and a negative one is impossible. The check fires before any subprocess is spawned.

Source

Thrown at eval/workflow_bench/process_control.py:430

    *,
    cwd: Path | str | None = None,
    env: Mapping[str, str] | None = None,
    shell: bool = False,
    timeout: float,
    terminate_grace: float = DEFAULT_TERMINATE_GRACE,
    tail_bytes: int = MAX_TAIL_BYTES,
    require_pid_namespace: bool = False,
    stdin_data: bytes | None = None,
    capture_stdout_bytes: int | None = None,
    _ownership_slot: list[tuple[subprocess.Popen[bytes], _WindowsJob | None, int | None]],
) -> ManagedProcessResult:
    """Implementation registered with an outer post-spawn ownership guard."""

    started = time.monotonic()
    if timeout <= 0 or terminate_grace < 0 or tail_bytes <= 0:
        raise ValueError("timeout and tail_bytes must be positive; terminate_grace must be non-negative")
    if capture_stdout_bytes is not None and capture_stdout_bytes <= 0:
        raise ValueError("capture_stdout_bytes must be positive when supplied")
    if require_pid_namespace:
        if os.name == "nt":
            return _empty_result("ownership-failure", started, "PID-namespace execution is not supported on Windows")
        if not _pid_namespace_wrapper(command, shell):
            return _empty_result(
                "ownership-failure",
                started,
                "required Bubblewrap --unshare-pid/--die-with-parent ownership is absent",
            )

    try:
        process, job, ownership = _spawn(
            command,
            cwd=cwd,
            env=env,
            shell=shell,
            pipe_stdin=stdin_data is not None,
            ownership_slot=_ownership_slot,

View on GitHub (pinned to d540b00184)

Solutions

  1. Omit capture_stdout_bytes entirely when full capture is not needed (the default None is correct).
  2. If driven by config, convert 0 / negative to None before the call: `cap or None`.
  3. Add an assertion at the call site: `assert capture_stdout_bytes is None or capture_stdout_bytes > 0`.
  4. Write a unit test that exercises both None and a positive value.

Example fix

// before
run_managed(cmd, timeout=60, capture_stdout_bytes=config.get('cap', 0))
// after
cap = config.get('cap') or None
run_managed(cmd, timeout=60, capture_stdout_bytes=cap)
Defensive patterns

Strategy: validation

Validate before calling

def normalize_capture(capture_stdout_bytes: int | None) -> int | None:
    if capture_stdout_bytes is None:
        return None
    if capture_stdout_bytes <= 0:
        raise ValueError('capture_stdout_bytes must be > 0 when supplied')
    return capture_stdout_bytes

# run_managed(..., capture_stdout_bytes=normalize_capture(cfg.get('cap')))

Prevention

When it happens

Trigger: Calling run_managed with capture_stdout_bytes=0 or negative. Typically a code path that sets the kwarg unconditionally from an optional config without gating on None.

Common situations: Reading capture_stdout_bytes from config that returns 0 for 'unset'; arithmetic that subtracts into the negatives; copy-paste from another call site that legitimately omitted the kwarg.

Related errors


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