{"id":"8bc888de769557cb","repo":"pytest-dev/pytest","slug":"found-2-or-more-testreports-matching-inamepart-r","errorCode":null,"errorMessage":"found 2 or more testreports matching {inamepart!r}: {values}","messagePattern":"found 2 or more testreports matching (.+?): (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/pytester.py","lineNumber":379,"sourceCode":"        when: str | None = None,\n    ) -> CollectReport | TestReport:\n        \"\"\"Return a testreport whose dotted import path matches.\"\"\"\n        values = []\n        for rep in self.getreports(names=names):\n            if not when and rep.when != \"call\" and rep.passed:\n                # setup/teardown passing reports - let's ignore those\n                continue\n            if when and rep.when != when:\n                continue\n            if not inamepart or inamepart in rep.nodeid.split(\"::\"):\n                values.append(rep)\n        if not values:\n            raise ValueError(\n                f\"could not find test report matching {inamepart!r}: \"\n                \"no test reports at all!\"\n            )\n        if len(values) > 1:\n            raise ValueError(\n                f\"found 2 or more testreports matching {inamepart!r}: {values}\"\n            )\n        return values[0]\n\n    @overload\n    def getfailures(\n        self,\n        names: Literal[\"pytest_collectreport\"],\n    ) -> Sequence[CollectReport]: ...\n\n    @overload\n    def getfailures(\n        self,\n        names: Literal[\"pytest_runtest_logreport\"],\n    ) -> Sequence[TestReport]: ...\n\n    @overload\n    def getfailures(","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/pytester.py#L361-L397","documentation":"Raised by Pytester.matchreport when more than one report matches the inamepart filter, making the selection ambiguous. Because matchreport must return exactly one report, an ambiguous match is rejected. The matching logic compares inamepart against each part of the node id split on '::', so a short or common substring matches many tests.","triggerScenarios":"Calling matchreport with an inamepart that is a substring of multiple test node ids (e.g. 'test_' matches every test), or when setup/teardown/call reports all match because 'when' is not specified and reports failed.","commonSituations":"Tests with shared name prefixes; passing a generic substring instead of a full test name; parametrized tests whose ids share a stem; not passing the 'when' argument when multiple phases produced non-passed reports.","solutions":["Pass a more specific inamepart that uniquely identifies a single test (include the function name and, if needed, the parametrization id).","Pass the 'when' argument (e.g. when=\"call\") to narrow which phase's report is matched.","Use getreports() directly and filter in your own test code when ambiguity is expected.","Rename colliding tests so node ids are distinguishable."],"exampleFix":"// before\nrep = reprec.matchreport(\"test_\")  # matches all tests\n// after\nrep = reprec.matchreport(\"test_login::test_success\", when=\"call\")","handlingStrategy":"validation","validationCode":"candidates = [r for r in reprec.getreports()\n              if \"test_foo\" in r.nodeid.split(\"::\")]\nif len(candidates) > 1:\n    raise AssertionError(f\"ambiguous; refine inamepart. matches: {candidates}\")\nrep = reprec.matchreport(\"test_foo::specific_case\")","typeGuard":null,"tryCatchPattern":"try:\n    rep = reprec.matchreport(inamepart, when=\"call\")\nexcept ValueError as e:\n    if \"2 or more\" in str(e):\n        inamepart = make_it_more_specific(inamepart)\n        rep = reprec.matchreport(inamepart, when=\"call\")\n    else:\n        raise","preventionTips":["Pass full node-id-style substrings including parametrization ids.","Specify the 'when' argument to disambiguate phases.","Use unique test function names."],"tags":["pytester","test-reports","assertion"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}