pytest-dev/pytest · error · ValueError
cannot delete key in keywords dict
Error message
cannot delete key in keywords dict
What it means
`NodeKeywords` is the keyword mapping attached to every test node. Its `__delitem__` is implemented to unconditionally raise ValueError, so `del node.keywords[name]` is never allowed — node keywords are derived from marks/node identity and are not user-mutable.
Source
Thrown at src/_pytest/mark/structures.py:682
# Note: we could've avoided explicitly implementing some of the methods
# below and use the collections.abc fallback, but that would be slow.
def __contains__(self, key: object) -> bool:
return key in self._markers or (
self.parent is not None and key in self.parent.keywords
)
def update( # type: ignore[override]
self,
other: Mapping[str, Any] | Iterable[tuple[str, Any]] = (),
**kwds: Any,
) -> None:
self._markers.update(other)
self._markers.update(kwds)
def __delitem__(self, key: str) -> None:
raise ValueError("cannot delete key in keywords dict")
def __iter__(self) -> Iterator[str]:
# Doesn't need to be fast.
yield from self._markers
if self.parent is not None:
for keyword in self.parent.keywords:
# self._marks and self.parent.keywords can have duplicates.
if keyword not in self._markers:
yield keyword
def __len__(self) -> int:
# Doesn't need to be fast.
return sum(1 for keyword in self)
def __repr__(self) -> str:
return f"<NodeKeywords for node {self.node}>"
View on GitHub (pinned to 98b357f69e)
Solutions
- Do not mutate `keywords` directly; instead deselect the item or apply/remove marks.
- To change selection, filter `items` in your hook or use `-k`/`-m`.
- If you need custom data on a node, use `item.stash` or `item.user_properties`.
Example fix
# before
def pytest_collection_modifyitems(items):
del items[0].keywords['xfail']
# after
def pytest_collection_modifyitems(items):
items[:] = [i for i in items if 'xfail' not in i.keywords] Defensive patterns
Strategy: validation
Validate before calling
def safe_filter_keywords(items, drop):
return [i for i in items if drop not in i.keywords] # never `del item.keywords[...]` Prevention
- Treat `node.keywords` as read-only.
- Use marks, `item.stash`, or `user_properties` for mutable per-node data.
When it happens
Trigger: Calling `del item.keywords['something']` in a `pytest_collection_modifyitems` hook or any plugin that manipulates a node's `keywords` mapping.
Common situations: Plugins/hooks trying to remove a keyword to suppress selection; assuming `keywords` behaves like a normal dict.
Related errors
- absolute tolerance can't be NaN.
- relative tolerance can't be negative: {relative_tolerance}
- relative tolerance can't be NaN.
- pytest.approx() does not support relative tolerance for date
- pytest.approx() does not support nan_ok for datetime/timedel
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/42adf7853bcf6af7.json.
Report an issue: GitHub.