# pytest mark not registered

Classification: dependency
Frameworks: pytest, CI
Canonical: https://automationtester.in/failures/pytest-unknown-mark

## Recognizable error

```text
'smoke' not found in `markers` configuration option
```

## What it means

A test uses a custom mark pytest does not know. Without strict markers that is only a PytestUnknownMarkWarning; with strict markers on, collection of that file fails and nothing in it runs.

## Minimal repro

Run on 2026-10-23 with pytest 9.1.1, pytest-xdist 3.8.0 (installed, for the plugin cause), Python 3.11.14.

test_checkout.py:

```python
import pytest


@pytest.mark.smoke
def test_checkout_total():
    assert 2 + 2 == 4
```

command:

```shell
python -m pytest -q --strict-markers
```

output:

```text
______________________ ERROR collecting test_checkout.py _______________________
'smoke' not found in `markers` configuration option
=========================== short test summary info ============================
ERROR test_checkout.py - Failed: 'smoke' not found in `markers` configuration...
!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
1 error in 0.04s

# Without --strict-markers the same file prints 1 passed, 1 warning, with:
test_checkout.py:4: PytestUnknownMarkWarning: Unknown pytest.mark.smoke - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
```

## Ranked causes, checks, and fixes

### 1. The mark was never registered

Custom marks have to be listed in the markers option or added in a pytest_configure hook. Strictness can come from --strict-markers, from strict_markers in config, or from the pytest 9 strict option, which turns strict_markers on along with three other checks. A pytest.ini containing only strict = true failed the repro the same way.

Diagnostic: Run `pytest --markers` and look for the name. Then search the config and CI command for strict, strict_markers and --strict-markers.

Fix: Register the mark with a one-line description in the config file pytest actually reads.

### 2. The mark is registered in a file pytest is not reading

pytest uses exactly one config file, and pytest.ini wins over pyproject.toml even when it is empty. We registered smoke in pyproject.toml, then added an empty pytest.ini: the run failed again, and the header said configfile: pytest.ini (WARNING: ignoring pytest config in pyproject.toml!).

Diagnostic: Read the configfile: line in the session header of the failing run, locally and in CI. A different rootdir (running pytest from another directory) changes which file is found.

Fix: Keep one pytest config file, delete the stray one, and run pytest from the repository root in CI.

### 3. A plugin that registers the mark is not loaded

Plugins register their own marks when they load. With pytest-xdist installed, @pytest.mark.xdist_group passed under --strict-markers; with -p no:xdist the same file failed with 'xdist_group' not found in `markers` configuration option.

Diagnostic: Check the plugins: line in the session header against the plugin that owns the mark, and compare the CI dependency lock with your local environment.

Fix: Install the plugin in the CI test environment. Do not register the plugin's mark yourself; that would hide the missing plugin.

## Verified fix

Register the mark in the config file pytest reports in its header.

pytest.ini:

```ini
[pytest]
markers =
    smoke: fast checks that gate every pull request
```

Evidence: Re-run on 2026-10-23 with pytest 9.1.1 on Python 3.11.14: after adding that pytest.ini, `pytest --strict-markers` printed 1 passed and its header read configfile: pytest.ini. The summary line of the failing run is cut at the terminal width, so the full markers text is on the line under the ERROR collecting banner.

## When this is not the cause

- **A misspelt parametrize.** pytest catches that one separately: @pytest.mark.parameterize fails with Unknown 'parameterize' mark, did you mean 'parametrize'? Registering a parameterize marker would silence the real bug.
- **Warnings promoted to errors.** With -W error::pytest.PytestUnknownMarkWarning the failure is a traceback ending in the warning text, not the markers message. The fix is still registration, but the strict setting to look for is the filterwarnings option.
- **The test itself.** The error is raised while the module is collected, before any test runs. Nothing inside the test body matters.

## Prevention

- Turn on strict markers in the shared config so a typo fails locally, not only in CI.
- Keep a single pytest config file and review any new one in code review.
- Lock test plugins in the same dependency group CI installs.

## Primary references

- [pytest: how to mark test functions, registering marks](https://docs.pytest.org/en/stable/how-to/mark.html)
- [pytest: configuration file precedence](https://docs.pytest.org/en/stable/reference/customize.html)
- [pytest reference: markers, strict_markers and strict](https://docs.pytest.org/en/stable/reference/reference.html)

Triage this failure locally: https://automationtester.in/tools/test-failure-triage