pytest-dev/pytest · error · ValueError

@pytest.fixture is being applied more than once to the same…

Error message

@pytest.fixture is being applied more than once to the same function {function.__name__!r}

What it means

fixtures.py:1430 detects that @pytest.fixture is being stacked: the function passed to __call__ is already a FixtureFunctionDefinition (the wrapper pytest produced on the first decoration). pytest does not allow re-decoration; the second application raises ValueError naming the function. This usually comes from a typo or a decorator factory returning another @pytest.fixture.

Solutions

  1. Remove the duplicate @pytest.fixture line, keeping exactly one.
  2. If using a custom factory decorator, have it return the raw function and apply @pytest.fixture only once at the call site.
  3. Search the file for repeated decorator usage via grep.

Example fix

// before
@pytest.fixture
@pytest.fixture
def cache():
    return {}
// after
@pytest.fixture
def cache():
    return {}
Defensive patterns

Strategy: validation

Validate before calling

# In a pre-commit grep, flag consecutive @pytest.fixture lines.
# Or via AST: ensure FixtureFunctionDefinition is not re-wrapped.
import pathlib
for f in pathlib.Path('tests').rglob('*.py'):
    txt = f.read_text()
    assert '@pytest.fixture\n@ pytest.fixture' not in txt.replace(' ',''), f'{f} has stacked fixtures'

Prevention

When it happens

Trigger: Writing '@pytest.fixture\n@pytest.fixture\ndef foo(): ...'; a custom decorator that itself applies @pytest.fixture being combined with an explicit @pytest.fixture; programmatically wrapping a fixture with the marker twice.

Common situations: Copy-paste leaving two decorator lines; refactoring a helper into a fixture while the original @pytest.fixture is still on the function; conflicting plugin/helper decorators that both mark fixtures.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/f7b5755152b533cb. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/fixtures.py:1430

@dataclasses.dataclass(frozen=True)
class FixtureFunctionMarker:
    scope: ScopeName | Callable[[str, Config], ScopeName]
    params: tuple[object, ...] | None
    autouse: bool = False
    ids: tuple[object | None, ...] | Callable[[Any], object | None] | None = None
    name: str | None = None

    _ispytest: dataclasses.InitVar[bool] = False

    def __post_init__(self, _ispytest: bool) -> None:
        check_ispytest(_ispytest)

    def __call__(self, function: FixtureFunction) -> FixtureFunctionDefinition:
        if inspect.isclass(function):
            raise ValueError("class fixtures not supported (maybe in the future)")

        if isinstance(function, FixtureFunctionDefinition):
            raise ValueError(
                f"@pytest.fixture is being applied more than once to the same function {function.__name__!r}"
            )

        if hasattr(function, "pytestmark"):
            fail(
                "Marks cannot be applied to fixtures.\n"
                "See docs: https://docs.pytest.org/en/stable/deprecations.html#applying-a-mark-to-a-fixture-function"
            )

        fixture_definition = FixtureFunctionDefinition(
            function=function, fixture_function_marker=self, _ispytest=True
        )

        name = self.name or function.__name__
        if name == "request":
            location = getlocation(function)
            fail(
                f"'request' is a reserved word for fixtures, use another name:\n  {location}",

View on GitHub (pinned to 0d6fbdeffa)