{"id":"a3107118311618bb","repo":"pytest-dev/pytest","slug":"request-fixturename-did-not-yield-a-value","errorCode":null,"errorMessage":"{request.fixturename} did not yield a value","messagePattern":"(.+?) did not yield a value","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/fixtures.py","lineNumber":1061,"sourceCode":"            for line in lines[1:]:\n                tw.line(\n                    f\"{ExceptionInfoFormatter.flow_marker}       {line.strip()}\",\n                    red=True,\n                )\n        tw.line()\n        tw.line(f\"{os.fspath(self.filename)}:{self.firstlineno + 1}\")\n\n\ndef call_fixture_func(\n    fixturefunc: _FixtureFunc[FixtureValue], request: FixtureRequest, kwargs\n) -> FixtureValue:\n    if inspect.isgeneratorfunction(fixturefunc):\n        fixturefunc = cast(Callable[..., Generator[FixtureValue]], fixturefunc)\n        generator = fixturefunc(**kwargs)\n        try:\n            fixture_result = next(generator)\n        except StopIteration:\n            raise ValueError(f\"{request.fixturename} did not yield a value\") from None\n        finalizer = functools.partial(_teardown_yield_fixture, fixturefunc, generator)\n        request.addfinalizer(finalizer)\n    else:\n        fixturefunc = cast(Callable[..., FixtureValue], fixturefunc)\n        fixture_result = fixturefunc(**kwargs)\n    return fixture_result\n\n\ndef _teardown_yield_fixture(fixturefunc, it) -> None:\n    \"\"\"Execute the teardown of a fixture function by advancing the iterator\n    after the yield and ensure the iteration ends (if not it means there is\n    more than one yield in the function).\"\"\"\n    try:\n        next(it)\n    except StopIteration:\n        pass\n    else:\n        fs, lineno = getfslineno(fixturefunc)","sourceCodeStart":1043,"sourceCodeEnd":1079,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/fixtures.py#L1043-L1079","documentation":"Raised in `call_fixture_func` when a generator-style fixture function (one containing `yield`) returns without ever yielding a value (StopIteration on the first `next()`). pytest treats generator fixtures as setup/teardown pairs and requires exactly one yielded value, so a generator that exits before yielding has no setup value to inject.","triggerScenarios":"A `@pytest.fixture` generator function that conditionally returns before the yield, e.g. `def f():\\n    if skip: return\\n    yield 1`, or an accidentally empty generator. The first `next()` raises StopIteration which pytest converts to ValueError naming the fixture.","commonSituations":"Adding an early `return` guard for a conditional skip inside a yielding fixture. Refactoring a fixture so the yield is inside an `if` branch. Misplaced `return` instead of `continue`.","solutions":["Ensure the generator always reaches exactly one `yield` on every code path; move guards outside the fixture or use pytest.mark.skip.","If you sometimes have nothing to provide, yield a sentinel (e.g. `yield None`) unconditionally.","Split conditional setup into a non-generator fixture returning a value and a separate teardown via `request.addfinalizer`."],"exampleFix":"// before\n@pytest.fixture\ndef conn(request):\n    if not ENABLED:\n        return                 # -> did not yield a value\n    c = open()\n    yield c\n    c.close()\n// after\n@pytest.fixture\ndef conn(request):\n    if not ENABLED:\n        pytest.skip(\"disabled\")\n    c = open()\n    yield c\n    c.close()","handlingStrategy":"validation","validationCode":"import inspect\n\ndef safe_fixture(fn):\n    if inspect.isgeneratorfunction(fn):\n        gen = fn()\n        try:\n            next(gen)\n        except StopIteration:\n            raise ValueError(f\"{fn.__name__} did not yield\")\n    return fn","typeGuard":"def always_yields(fn) -> bool:\n    import ast, inspect\n    if not inspect.isgeneratorfunction(fn):\n        return True\n    tree = ast.parse(inspect.getsource(fn))\n    return any(isinstance(n, ast.Yield) for n in ast.walk(tree))","tryCatchPattern":null,"preventionTips":["Ensure every code path in a generator fixture reaches exactly one yield.","Use pytest.skip() instead of early return for conditional fixtures.","Yield a sentinel (None) when there is nothing to provide."],"tags":["pytest","fixtures","generator","yield","valueerror"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}