python/cpython · error · RuntimeError

Unrecognized action (%r) in warnings.filters: %s

Error message

Unrecognized action (%r) in warnings.filters:
 %s

What it means

Raised while a warning is being dispatched when the filter entry selected for it carries an action the matching engine does not recognize. filterwarnings/simplefilter validate actions at insertion time, so this error is a signature that warnings.filters was mutated directly (insert/append of hand-built tuples) with an invalid action string. It surfaces only when a warning actually matches the corrupt entry, making it late and confusing.

Source

Thrown at Lib/_py_warnings.py:613

        if action == "once":
            registry[key] = 1
            oncekey = (text, category)
            if _wm.onceregistry.get(oncekey):
                return
            _wm.onceregistry[oncekey] = 1
        elif action in {"always", "all"}:
            pass
        elif action == "module":
            registry[key] = 1
            altkey = (text, category, 0)
            if registry.get(altkey):
                return
            registry[altkey] = 1
        elif action == "default":
            registry[key] = 1
        else:
            # Unrecognized actions are errors
            raise RuntimeError(
                  "Unrecognized action (%r) in warnings.filters:\n %s" %
                  (action, item))

    # Prime the linecache for formatting, in case the
    # "file" is actually in a zipfile or something.
    import linecache
    linecache.getlines(filename, module_globals)

    # Print message and context
    msg = _wm.WarningMessage(message, category, filename, lineno,
                             module=module, source=source)
    _wm._showwarnmsg(msg)


class WarningMessage(object):

    _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
                        "line", "source", "module")

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Replace direct list mutation with warnings.filterwarnings()/simplefilter(), which validate
  2. Audit any code that touches warnings.filters for hand-built tuples
  3. If you must write filters directly, restrict actions to error/ignore/always/all/default/module/once
  4. Wrap suspicious blocks in catch_warnings(record=True) to isolate which filter entry is bad

Example fix

# before
warnings.filters.insert(0, ('suppress', None, UserWarning, None, 0))  # later -> RuntimeError

# after
warnings.filterwarnings('ignore', category=UserWarning)
Defensive patterns

Strategy: validation

Validate before calling

VALID_ACTIONS = {'error', 'ignore', 'always', 'all', 'default', 'module', 'once'}

def validate_filters() -> None:
    """Call before running code that emits warnings."""
    import warnings
    for i, item in enumerate(warnings.filters):
        if item[0] not in VALID_ACTIONS:
            raise ValueError(f'warnings.filters[{i}] has invalid action {item[0]!r}: {item}')

Type guard

def has_valid_filters() -> bool:
    import warnings
    valid = {'error', 'ignore', 'always', 'all', 'default', 'module', 'once'}
    return all(item[0] in valid for item in warnings.filters)

Try / catch

import warnings
try:
    warnings.warn('probe')
except RuntimeError as e:
    if 'Unrecognized action' in str(e):
        warnings.filters[:] = [f for f in warnings.filters
                               if f[0] in {'error', 'ignore', 'always', 'all', 'default', 'module', 'once'}]
        warnings.warn('probe')
    else:
        raise

Prevention

When it happens

Trigger: warnings.filters.insert(0, ('suppress', re.compile('.*'), UserWarning, re.compile('.*'), 0)) followed by any UserWarning; copying filter tuples from another interpreter with different accepted actions; save/restore of filters across environments where one side accepted non-standard actions.

Common situations: Test harnesses and libraries that reach into warnings.filters as a list instead of using the API; pickled/restored filter state; mixed Python versions where a custom shim wrote filters directly; monkeypatching gone wrong.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/bb34ded716b8991c. Report an issue: GitHub.