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
- Use one of the four valid values: fd, sys, no, or tee-sys
- Check the [pytest] section of pyproject.toml / pytest.ini and the PYTEST_ADDOPTS env var for stray --capture= values
- 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
- 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 constructing pytest args programmatically, validate against the Literal get_args(_CaptureMethod)
- Audit PYTEST_ADDOPTS and addopts for stray --capture values when CI breaks
- Document the four valid values in your project README
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
- must be a directory, given
- must be a filename, given
- plugin cannot be disabled
- Blocking conftest files using -p is not supported: -p no
- Config file ' ' has an unsupported format. Supported…
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)