pytest-dev/pytest · error · ValueError

unknown capturing method

Error message

unknown capturing method: {method!r}

What it means

Raised at the end of _get_multicapture() (src/_pytest/capture.py:723). _CaptureMethod (capture.py:46) is Literal['fd','sys','no','tee-sys']; the four branches at capture.py:713-722 cover them, so any other value hits the trailing ValueError. This is the final defensive raise after the if/elif chain.

Solutions

  1. Use one of the four valid values: fd, sys, no, or tee-sys
  2. Check the [pytest] section of pyproject.toml / pytest.ini and the PYTEST_ADDOPTS env var for stray --capture= values
  3. If invoking CaptureManager programmatically, type the variable as Literal['fd','sys','no','tee-sys'] (capture.py:46) so the typo is caught at typecheck time
  4. Remove the override entirely to fall back to the default 'fd'

Example fix

// before
# pytest.ini
[pytest]
addopts = --capture=tty
// after
[pytest]
addopts = --capture=tee-sys
Defensive patterns

Strategy: validation

Validate before calling

VALID = {'fd', 'sys', 'no', 'tee-sys'}
if method not in VALID:
    raise ValueError(f'capture must be one of {VALID}, got {method!r}')

Type guard

from typing import Literal, get_args
from _pytest.capture import _CaptureMethod
_VALID_CAPTURE = set(get_args(_CaptureMethod))  # {'fd','sys','no','tee-sys'}
def is_valid_capture(m: str) -> bool:
    return m in _VALID_CAPTURE

Try / catch

try:
    from _pytest.capture import _get_multicapture
    cap = _get_multicapture(method)
except ValueError as e:
    print(f'Bad --capture value: {e}')

Prevention

When it happens

Trigger: Passing an unrecognized value to --capture on the CLI, the `capture` ini option in pyproject.toml/pytest.ini/setup.cfg, or constructing MultiCapture directly via _get_multicapture with a custom string. A typo like --capture=tty-sys or capture = fd,sys reaches capture.py:723.

Common situations: Typo in pytest.ini's `addopts = --capture=...`, porting an old config from another runner (nosetests capture names), or a plugin that overrides the capture option with an invalid value.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/8fee4b32363a3774. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/capture.py:723

    def readouterr(self) -> CaptureResult[AnyStr]:
        out = self.out.snap() if self.out else ""
        err = self.err.snap() if self.err else ""
        # TODO: This type error is real, need to fix.
        return CaptureResult(out, err)  # type: ignore[arg-type]


def _get_multicapture(method: _CaptureMethod) -> MultiCapture[str]:
    if method == "fd":
        return MultiCapture(in_=FDCapture(0), out=FDCapture(1), err=FDCapture(2))
    elif method == "sys":
        return MultiCapture(in_=SysCapture(0), out=SysCapture(1), err=SysCapture(2))
    elif method == "no":
        return MultiCapture(in_=None, out=None, err=None)
    elif method == "tee-sys":
        return MultiCapture(
            in_=None, out=SysCapture(1, tee=True), err=SysCapture(2, tee=True)
        )
    raise ValueError(f"unknown capturing method: {method!r}")


# CaptureManager and CaptureFixture


class CaptureManager:
    """The capture plugin.

    Manages that the appropriate capture method is enabled/disabled during
    collection and each test phase (setup, call, teardown). After each of
    those points, the captured output is obtained and attached to the
    collection/runtest report.

    There are two levels of capture:

    * global: enabled by default and can be suppressed by the ``-s``
      option. This is always enabled/disabled during collection and each test
      phase.

View on GitHub (pinned to 0d6fbdeffa)