python/cpython · error · ValueError
invalid option name {option_string!r} for BooleanOptionalAct
Error message
invalid option name {option_string!r} for BooleanOptionalAction What it means
BooleanOptionalAction auto-generates a negated form for each option ('--foo' -> '--no-foo'). For two-dash options it refuses names that already start with 'no-' after the dashes ('--no-x'), because the generated negative would collide or be nonsensical ('--no-no-x'). The ValueError is raised at construction time, i.e. when the parser is built.
Source
Thrown at Lib/argparse.py:1063
class BooleanOptionalAction(Action):
def __init__(self,
option_strings,
dest,
default=None,
required=False,
help=None,
deprecated=False):
_option_strings = []
neg_option_strings = []
for option_string in option_strings:
_option_strings.append(option_string)
if len(option_string) > 2 and option_string[0] == option_string[1]:
# two-dash long option: '--foo' -> '--no-foo'
if option_string.startswith('no-', 2):
raise ValueError(f'invalid option name {option_string!r} '
f'for BooleanOptionalAction')
option_string = option_string[:2] + 'no-' + option_string[2:]
_option_strings.append(option_string)
neg_option_strings.append(option_string)
elif len(option_string) > 2 and option_string[0] != option_string[1]:
# single-dash long option: '-foo' -> '-nofoo'
if option_string.startswith('no', 1):
raise ValueError(f'invalid option name {option_string!r} '
f'for BooleanOptionalAction')
option_string = option_string[:1] + 'no' + option_string[1:]
_option_strings.append(option_string)
neg_option_strings.append(option_string)
super().__init__(
option_strings=_option_strings,
dest=dest,
nargs=0,
default=default,View on GitHub (pinned to bc6749cc3b)
Solutions
- Drop the 'no-' prefix and let the action generate it: add_argument('--cache', action=BooleanOptionalAction) gives --cache/--no-cache.
- If the flag must keep its literal name, use a plain store_true/store_false action instead.
- Strip 'no-' prefixes when generating options from config keys before passing them to add_argument.
Example fix
# before
parser.add_argument('--no-cache', action=argparse.BooleanOptionalAction) # ValueError at parser build
# after
parser.add_argument('--cache', action=argparse.BooleanOptionalAction) # provides --cache and --no-cache Defensive patterns
Strategy: validation
Validate before calling
def ok_boolean_option_name(name: str) -> bool:
if name.startswith('--'):
return not name.startswith('--no-')
return True Prevention
- Name positive flags without the 'no-' prefix; BooleanOptionalAction generates the negative
- Validate generated option names before add_argument
- Keep legacy negated flags on store_true instead of BooleanOptionalAction
When it happens
Trigger: parser.add_argument('--no-cache', action=argparse.BooleanOptionalAction); any long option string beginning '--no-'; programmatically prefixed option names from a config loop.
Common situations: Teams naming flags with a built-in negative ('--no-color', '--no-cache') and then adding BooleanOptionalAction for it; wrapping existing negated flags with the new action during a CLI modernization.
Related errors
- invalid nargs value
- .__call__() not defined
- nargs for store actions must be != 0; if you have nothing to
- nargs must be %r to supply const
- unknown parser %(parser_name)r (choices: %(choices)s)
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/3a3f0a3778b54ba4.
Report an issue: GitHub.