{"record":{"id":"a29daba0c7e7795a","repo":"pytest-dev/pytest","slug":"line-fnline-r-not-found-in-output","errorCode":null,"errorMessage":"line {fnline!r} not found in output","messagePattern":"line (.+?) not found in output","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/pytester.py","lineNumber":1634,"sourceCode":"        for line in lines2:\n            for x in self.lines:\n                if line == x or match_func(x, line):\n                    self._log(\"matched: \", repr(line))\n                    break\n            else:\n                msg = f\"line {line!r} not found in output\"\n                self._log(msg)\n                self._fail(msg)\n\n    def get_lines_after(self, fnline: str) -> Sequence[str]:\n        \"\"\"Return all lines following the given line in the text.\n\n        The given line can contain glob wildcards.\n        \"\"\"\n        for i, line in enumerate(self.lines):\n            if fnline == line or fnmatch(line, fnline):\n                return self.lines[i + 1 :]\n        raise ValueError(f\"line {fnline!r} not found in output\")\n\n    def _log(self, *args) -> None:\n        self._log_output.append(\" \".join(str(x) for x in args))\n\n    @property\n    def _log_text(self) -> str:\n        return \"\\n\".join(self._log_output)\n\n    def fnmatch_lines(\n        self, lines2: Sequence[str], *, consecutive: bool = False\n    ) -> None:\n        \"\"\"Check lines exist in the output (using :func:`python:fnmatch.fnmatch`).\n\n        The argument is a list of lines which have to match and can use glob\n        wildcards.  If they do not match a pytest.fail() is called.  The\n        matches and non-matches are also shown as part of the error message.\n\n        :param lines2: String patterns to match.","sourceCodeStart":1616,"sourceCodeEnd":1652,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/pytester.py#L1616-L1652","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nafter = result.stdout.get_lines_after(\"== RESULTS ==\")\n// after\nprint('\\n'.join(result.stdout.lines))\nafter = result.stdout.get_lines_after(\"*RESULTS*\")","handlingStrategy":"validation","validationCode":"lines = result.stdout.lines\nif not any(fnline == l or fnmatch(l, fnline) for l in lines):\n    pytest.fail(f'anchor {fnline!r} not in output:\\n' + '\\n'.join(lines))\nafter = result.stdout.get_lines_after(fnline)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Inspect the captured lines before anchoring.","Use glob wildcards for variable content.","Confirm the marker writes to the same stream the matcher reads."],"tags":["pytester","linematcher","output-matching","validation"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}