python/cpython · error · ArgumentError
not allowed with argument
Error message
not allowed with argument %s
What it means
Raised by argparse when the command line supplies two or more options that belong to the same mutually exclusive group (created with parser.add_mutually_exclusive_group()). During parsing, argparse records every non-default action in seen_non_default_actions; when a later action's conflict list contains one already seen, it raises ArgumentError with the name of the earlier conflicting argument. The parse aborts before any action callback runs.
Solutions
- Pass only one option from the mutually exclusive group on the command line.
- If both behaviors are legitimately combinable, move the options out of the mutually exclusive group or put them in separate groups.
- Use a single option with choices (e.g. --output-format json|xml) instead of two exclusive flags.
- Catch the error programmatically: construct the parser with exit_on_error=False and catch argparse.ArgumentError to emit a custom message.
Example fix
# before
g = parser.add_mutually_exclusive_group()
g.add_argument('--json', action='store_true')
g.add_argument('--xml', action='store_true')
# `prog --json --xml` -> error: not allowed with argument --json
# after
parser.add_argument('--output-format', choices=['json', 'xml'], default='json') Defensive patterns
Strategy: try-catch
Validate before calling
import sys
def group_members_conflict(parser, argv):
# crude pre-check: count how many option strings from any
# mutually exclusive group appear in argv
for group in parser._mutually_exclusive_groups:
names = {s for a in group._group_actions for s in a.option_strings}
hits = [a for a in argv if a.split('=')[0] in names]
if len(hits) > 1:
return f'conflicting options: {" ".join(hits)}'
return None Try / catch
import argparse
parser = argparse.ArgumentParser(exit_on_error=False)
try:
args = parser.parse_args(argv)
except argparse.ArgumentError as e:
# e.argument identifies the offending action
print(f'usage error: {e}', file=sys.stderr)
sys.exit(2) Prevention
- Model either/or behavior with choices on a single option instead of mutually exclusive groups when conflicts are common.
- Document exclusive flags right next to each other in --help via container group titles.
- In test suites, assert that each realistic argv combination parses or fails with ArgumentError.
When it happens
Trigger: parser.add_mutually_exclusive_group() registers options A and B; the user passes both A and B (e.g. `prog --json --xml`). Also triggered when one group member gets a value from an explicit `--opt=v` form or an abbreviation that resolves to a group member, and when group members carry non-None defaults that the user overrides explicitly on a line where another member was already given.
Common situations: CLI flags that logically exclude each other (--verbose/--quiet, --json/--xml, --input/--stdin); adding a new flag to an existing mutually exclusive group and forgetting the constraint; users combining short aliases like -v and -q in scripts generated by other tools.
Related errors
- one of the arguments
- ambiguous option: %(option)s could match %(matches)s
- .__call__() not defined
- can't open '%(filename)s': %(error)s
- expected argument
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/4a1149e21639a2a9.
Report an issue: GitHub.
Appendix: source
Thrown at Lib/argparse.py:2261
# converts arg strings to the appropriate and then takes the action
seen_actions = set()
seen_non_default_actions = set()
warned = set()
def take_action(action, argument_strings, option_string=None):
seen_actions.add(action)
argument_values = self._get_values(action, argument_strings)
# error if this argument is not allowed with other previously
# seen arguments
if action.option_strings or argument_strings:
seen_non_default_actions.add(action)
for conflict_action in action_conflicts.get(action, []):
if conflict_action in seen_non_default_actions:
msg = _('not allowed with argument %s')
action_name = _get_action_name(conflict_action)
raise ArgumentError(action, msg % action_name)
# take the action if we didn't receive a SUPPRESS value
# (e.g. from a default)
if argument_values is not SUPPRESS:
action(self, namespace, argument_values, option_string)
# function to convert arg_strings into an optional action
def consume_optional(start_index):
# get the optional identified at this index
option_tuples = option_string_indices[start_index]
# if multiple actions match, the option string was ambiguous
if len(option_tuples) > 1:
options = ', '.join([option_string
for action, option_string, sep, explicit_arg in option_tuples])
args = {'option': arg_strings[start_index], 'matches': options}
msg = _('ambiguous option: %(option)s could match %(matches)s')
raise ArgumentError(None, msg % args)View on GitHub (pinned to bc6749cc3b)