pytest-dev/pytest · error · ValueError

warning must be an instance of Warning or subclass, got {war

Error message

warning must be an instance of Warning or subclass, got {warning!r}

What it means

Node.warn expects an instance of Warning (or a subclass such as PytestWarning / UserWarning). Passing a string, an exception, or any non-Warning object raises ValueError early so the warning machinery does not fail later with a generic type error.

Source

Thrown at src/_pytest/nodes.py:258

        :param Warning warning:
            The warning instance to issue.

        :raises ValueError: If ``warning`` instance is not a subclass of Warning.

        Example usage:

        .. code-block:: python

            node.warn(PytestWarning("some message"))
            node.warn(UserWarning("some message"))

        .. versionchanged:: 6.2
            Any subclass of :class:`Warning` is now accepted, rather than only
            :class:`PytestWarning <pytest.PytestWarning>` subclasses.
        """
        # enforce type checks here to avoid getting a generic type error later otherwise.
        if not isinstance(warning, Warning):
            raise ValueError(
                f"warning must be an instance of Warning or subclass, got {warning!r}"
            )
        path, lineno = get_fslocation_from_item(self)
        assert lineno is not None
        warnings.warn_explicit(
            warning,
            category=None,
            filename=str(path),
            lineno=lineno + 1,
        )

    # Methods for ordering nodes.

    @property
    def nodeid(self) -> str:
        """A ::-separated string denoting its collection tree address."""
        return self._nodeid

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Wrap the message in a Warning subclass: node.warn(PytestWarning('message'))
  2. For generic warnings use UserWarning: node.warn(UserWarning('message'))

Example fix

// before
node.warn('deprecated usage')
// after
from _pytest.warning_types import PytestWarning
node.warn(PytestWarning('deprecated usage'))
Defensive patterns

Strategy: type-guard

Validate before calling

def safe_warn(node, warning):
    if not isinstance(warning, Warning):
        raise TypeError('expected Warning instance')
    node.warn(warning)

Type guard

def is_warning_instance(w) -> bool:
    return isinstance(w, Warning)

Prevention

When it happens

Trigger: Calling item.warn('some message') or item.warn(some_string_variable) instead of passing a Warning instance. The check rejects category=None / raw strings.

Common situations: Following a tutorial that pre-dates pytest 6.2 (which restricted to PytestWarning) or general confusion between warnings.warn(str) and node.warn(warning).

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/7e312bc3757250ae.json. Report an issue: GitHub.