python/cpython · error · ValueError
invalid action: {action!r}
Error message
invalid action: {action!r} What it means
Raised by warnings.filterwarnings when the action string is not one of the recognized filter actions: 'error', 'ignore', 'always', 'all', 'default', 'module', 'once'. The function validates its arguments up front because filter entries are consumed later by the matching engine, which cannot interpret unknown actions. 'all' is an alias of 'always'; there is no 'warn', 'hide', or 'once/module' style shorthand.
Source
Thrown at Lib/_py_warnings.py:267
return fw(msg.message, msg.category,
msg.filename, msg.lineno, msg.line)
return _wm._formatwarnmsg_impl(msg)
def filterwarnings(action, message="", category=Warning, module="", lineno=0,
append=False):
"""Insert an entry into the list of warnings filters (at the front).
'action' -- one of "error", "ignore", "always", "all", "default", "module",
or "once"
'message' -- a regex that the warning message must match
'category' -- a class that the warning must be a subclass of
'module' -- a regex that the module name must match
'lineno' -- an integer line number, 0 matches all warnings
'append' -- if true, append to the list of filters
"""
if action not in {"error", "ignore", "always", "all", "default", "module", "once"}:
raise ValueError(f"invalid action: {action!r}")
if not isinstance(message, str):
raise TypeError("message must be a string")
if not isinstance(category, type) or not issubclass(category, Warning):
raise TypeError("category must be a Warning subclass")
if not isinstance(module, str):
raise TypeError("module must be a string")
if not isinstance(lineno, int):
raise TypeError("lineno must be an int")
if lineno < 0:
raise ValueError("lineno must be an int >= 0")
if message or module:
import re
if message:
message = re.compile(message, re.I)
else:
message = NoneView on GitHub (pinned to bc6749cc3b)
Solutions
- Use one of the seven valid actions: error, ignore, always, all, default, module, once
- Strip/normalize user- or config-supplied actions: action.strip().lower() before calling
- Validate actions against the set when parsing config files, and reject early with a clear message
Example fix
# before
warnings.filterwarnings('ignore-once', category=DeprecationWarning) # ValueError
# after
warnings.filterwarnings('once', category=DeprecationWarning) Defensive patterns
Strategy: validation
Validate before calling
VALID_ACTIONS = {'error', 'ignore', 'always', 'all', 'default', 'module', 'once'}
def safe_filterwarnings(action, *args, **kwargs):
action = str(action).strip().lower()
if action not in VALID_ACTIONS:
raise ValueError(f'{action!r} is not a valid action; choose from {sorted(VALID_ACTIONS)}')
import warnings
return warnings.filterwarnings(action, *args, **kwargs) Type guard
def is_valid_action(action) -> bool:
return isinstance(action, str) and action.strip().lower() in {
'error', 'ignore', 'always', 'all', 'default', 'module', 'once'} Prevention
- Normalize config-sourced actions with .strip().lower() before calling filterwarnings
- Validate action names at config-load time so bad values fail loudly and early
- Remember 'all' == 'always'; there is no 'hide'/'suppress'/'warn' action
When it happens
Trigger: warnings.filterwarnings(action='suppress'/'hide'/'warn'/'ignore-once') — any misspelled or invented action string; also actions read from a config file and forwarded verbatim; actions with trailing whitespace or different casing ('Ignore') since the check is case-sensitive.
Common situations: Typo'd action names in test-suite bootstrap (pytest.ini-style warning config translated manually); actions loaded from YAML/JSON settings; snippets written for other warning systems (e.g. Ruby's $VERBOSE vocabulary); uppercase or padded values from user input.
Related errors
- message must be a string
- category must be a Warning subclass
- module must be a string
- lineno must be an int
- lineno must be an int >= 0
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/12b9dc7b228de1ac.
Report an issue: GitHub.