pytest-dev/pytest · error · ValueError

line {fnline!r} not found in output

Error message

line {fnline!r} not found in output

What it means

Raised by RunResult.get_lines_after when the requested fnline (which may contain glob wildcards, matched via fnmatch) does not appear anywhere in the captured output lines. get_lines_after returns all lines following the first match, so a total absence of a match is a hard failure.

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 98b357f69e)

Solutions

  1. Inspect result.stdout.str() to confirm the expected line and its exact formatting.
  2. Use fnmatch wildcards (e.g. '*marker*') if whitespace/details vary.
  3. Search the correct stream (stdout vs stderr) — get_lines_after operates on self.lines.
  4. Update the expected line to match the current output of the code under test.

Example fix

// before
lines = result.get_lines_after("STARTED processing")
// after
lines = result.get_lines_after("*STARTED*processing*")
Defensive patterns

Strategy: validation

Validate before calling

from fnmatch import fnmatch

def line_exists(result, pattern: str) -> bool:
    return any(fnmatch(line, pattern) for line in result.stdout.lines)

if not line_exists(result, "*marker*"):
    raise AssertionError(f"marker not found; output:\n{result.stdout.str()}")
lines = result.get_lines_after("*marker*")

Try / catch

try:
    lines = result.get_lines_after(pattern)
except ValueError:
    print(result.stdout.str())
    raise

Prevention

When it happens

Trigger: Calling result.get_lines_after('some marker string') where that exact string (or wildcard pattern) is not present in stdout/stderr captured from the pytest run.

Common situations: Asserting on output that was suppressed (e.g. by -q or a custom reporter); a typo or stale expectation after changing the code under test; the line was emitted to a different stream than the one being searched; glob pattern uses incorrect wildcards.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/a29daba0c7e7795a.json. Report an issue: GitHub.