pytest-dev/pytest · error · ValueError
line not found in output
Error message
line {fnline!r} not found in output What it means
Thrown by LineMatcher.get_lines_after() when no line in the captured output exactly equals or fnmatches the requested fnline. It returns lines following a match; no match means no anchor was found.
Solutions
- Print the captured lines (print('\n'.join(matcher.lines))) to see what's actually there.
- Use a glob pattern with wildcards if the line has variable content.
- Confirm the marker is written to the same stream the LineMatcher is reading.
Example fix
// before
after = result.stdout.get_lines_after("== RESULTS ==")
// after
print('\n'.join(result.stdout.lines))
after = result.stdout.get_lines_after("*RESULTS*") Defensive patterns
Strategy: validation
Validate before calling
lines = result.stdout.lines
if not any(fnline == l or fnmatch(l, fnline) for l in lines):
pytest.fail(f'anchor {fnline!r} not in output:\n' + '\n'.join(lines))
after = result.stdout.get_lines_after(fnline) Prevention
- Inspect the captured lines before anchoring.
- Use glob wildcards for variable content.
- Confirm the marker writes to the same stream the matcher reads.
When it happens
Trigger: Calling result.stdout.get_lines_after('some marker') where 'some marker' never appears in the captured output; whitespace/encoding differences between expected and actual lines; glob pattern that doesn't match any line.
Common situations: Asserting on output structure where the anchor line was conditional and didn't print; trailing whitespace stripping differences; OS-specific line endings; output redirected such that the marker went to a different stream.
Related errors
- could not find test report matching
- ext must not be None
- invalid type for lines2
- pytester.makefile expects a file extension, try .
- absolute tolerance can't be negative
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/a29daba0c7e7795a.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/pytester.py:1634
for line in lines2:
for x in self.lines:
if line == x or match_func(x, line):
self._log("matched: ", repr(line))
break
else:
msg = f"line {line!r} not found in output"
self._log(msg)
self._fail(msg)
def get_lines_after(self, fnline: str) -> Sequence[str]:
"""Return all lines following the given line in the text.
The given line can contain glob wildcards.
"""
for i, line in enumerate(self.lines):
if fnline == line or fnmatch(line, fnline):
return self.lines[i + 1 :]
raise ValueError(f"line {fnline!r} not found in output")
def _log(self, *args) -> None:
self._log_output.append(" ".join(str(x) for x in args))
@property
def _log_text(self) -> str:
return "\n".join(self._log_output)
def fnmatch_lines(
self, lines2: Sequence[str], *, consecutive: bool = False
) -> None:
"""Check lines exist in the output (using :func:`python:fnmatch.fnmatch`).
The argument is a list of lines which have to match and can use glob
wildcards. If they do not match a pytest.fail() is called. The
matches and non-matches are also shown as part of the error message.
:param lines2: String patterns to match.View on GitHub (pinned to 0d6fbdeffa)