pytest-dev/pytest · error · ValueError

warning must be an instance of Warning or subclass, got

Error message

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

What it means

Raised by Node.warn when the argument is not an instance of Warning or a subclass. Since pytest 6.2 any Warning subclass is accepted (not just PytestWarning), but a non-Warning value (string, Exception, int) is rejected at line 258 with a ValueError before warnings.warn_explicit is called. This avoids a confusing generic type error downstream in the warnings machinery.

Solutions

  1. Wrap the message in a Warning subclass: node.warn(PytestWarning('message')).
  2. If using UserWarning or a custom warning, instantiate it first.
  3. Do not pass raw strings, ints, or non-Warning exceptions to warn().

Example fix

// before
node.warn('deprecated feature')
// after
import warnings
node.warn(warnings.UserWarning('deprecated feature'))
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(warning, Warning):
    raise ValueError('expected a Warning instance')

Type guard

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

Prevention

When it happens

Trigger: node.warn('some message string'); node.warn(Exception('x')); node.warn(42); passing a warning class instead of an instance like node.warn(PytestWarning).

Common situations: Developers pass a plain string expecting logging-style behavior; passing a warning class instead of an instantiated warning object.

Related errors


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

Appendix: 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 0d6fbdeffa)