Python’s argparse raises ArgumentError for a conflicting option string when two options reuse the same flag such as -h or –help.
What This Argparse ArgumentError Conflicting Option String Means
Quick check — When you see ArgumentError: argument --foo: conflicting option string(s): --foo, Python is telling you that two arguments in the same parser share the same option flag.
The argparse module keeps a registry of every short and long option string you add. If you add -f or --foo more than once on a single parser, or across parent parsers that feed into it, argparse refuses to guess which one you meant and raises this error before any command line is parsed.
It helps to separate the human facing flag from the internal name. The option string is the text the user types on the command line, such as --foo. The destination name is the attribute you read on the parsed namespace, such as args.foo, and multiple flags may share that same internal target safely.
Under the hood, the parser checks for conflicts every time you call add_argument(). If an option string is already taken, the new action collides with the existing one. That is why the traceback points at _check_conflict and _handle_conflict_error in argparse.py right before the message appears.
In many projects this pops up when a developer adds a flag that already exists in a parent parser, a shared helper, or a test tool like pytest. The arg list might look small in one file, yet a mix of imports and shared parsers means the same flag string is defined twice by the time everything is wired together.
Common Ways This Argparse Conflict Happens
Most cases fall into a few patterns. Once you know these, tracking the problem in your own code gets much easier.
- Redefining -h Or –help — By default
ArgumentParseradds-h/--help. If you calladd_argument('-h', '--help', ...)without turning the built in help off, the parser sees a second copy of the same option strings and raises the error. - Repeating A Custom Flag — A project might define
--browser,--host, or--timeoutin more than one place, such as both a base parser and a feature specific parser. When those parsers are combined, the duplicate option string causes a conflict. - Mixing Parents With Overlapping Options — Parent parsers are handy for shared flags, but if two parents both define the same
-vor--verbose, any child that includes both parents will trigger the error. - Plugins And Test Tools Adding Their Own Flags — Test runners and command line tools often extend argparse. A plugin might already own a flag like
-Vor--headless, so adding the same flag inside your own code leads to a conflict once the tool imports your parser.
Here is a tiny script that reproduces the problem with a repeated flag:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--foo')
parser.add_argument('--foo') # second use of --foo
# This line never runs, because add_argument() raised earlier
args = parser.parse_args()
If you run this script, Python raises the familiar message about a conflicting option string. The fix is to give one of the actions a different flag or to remove the duplicate entirely.
Fixing Conflicting Option Strings In Your Argument Parser
Once you hit the error, you need a simple way to find and correct the conflict. A quick scan of every add_argument() call helps, yet large projects benefit from a clear checklist.
- Search For The Flag Text — Use your editor’s search for the exact option string from the error message, such as
--browseror-V. You are looking for everyadd_argument()call that mentions that flag. - List All Parsers That Share Flags — Write down which
ArgumentParserinstances or helper functions define that option. Include parent parsers passed with theparentsargument and any factory functions that build parsers for subcommands. - Pick A Single Owner For Each Flag — Decide which parser should own a given flag. Shared flags like
--verboseor--configshould live in one base parser that others reuse instead of re declaring the same option string in every place. - Rename Or Remove Duplicates — Where the same flag appears twice, change one definition to a new short or long form. You might move from
-Vto-ror from--timeoutto--request-timeoutso each string is distinct. - Use conflict_handler=”resolve” With Care — Passing
conflict_handler='resolve'intoArgumentParsertells argparse to keep the newest definition and drop the older one. This can be handy when you truly want a newer parser to override a parent, yet it can also hide mistakes, so use it only when the override plan is clear.
Deeper fix — After you clean up the flags, run the script with --help and scan the options list. That output acts as the real map of which option strings ended up in the final parser and helps confirm that no duplicate or confusing spellings remain.
Handling Built In Help And Custom Usage Flags
One common source of the argparse argumenterror conflicting option string is the built in help flag. Every plain ArgumentParser() call adds a help option, so manually adding your own -h or --help collides with that default behavior.
- Turn Off Automatic Help When Needed — Create the parser with
add_help=Falseif you want full control over help flags. After that you may add your own help option using any flag names that fit your interface. - Keep Help Flags Aligned Across Parents — If you share a base parser through the
parentsargument, let only that base parser supply the help flag. Child parsers then inherit the same help behavior without defining their own help options. - Avoid Short Flag Collisions — Short options live in a small space. Reusing
-h,-v, or-qwith different meanings is tempting, yet in a large tool that choice leads straight to conflicts. Favor long names for project specific features.
Here is a safe way to take over help flags without raising conflicts:
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help', help='Show this help message.')
parser.add_argument('--version', action='store_true', help='Show version info.')
Because automatic help is off, your manual help option does not collide with another -h/--help. That keeps the parser clean while still giving you a custom help message or placement.
Working Cleanly With Parents And Subparsers
Large command line tools often build a base parser with shared options and then attach subparsers for each command. This pattern keeps help output tidy, yet the extra layers also make conflicts easier to miss.
When you use parent parsers, argparse merges all of their option strings into the child. If two parents both define --config, the child receives two definitions with the same string and the error appears as soon as the child parser is built.
- Define Shared Options In A Single Base Parser — Build one parser that holds cross cutting flags such as
--config,--log-level, and--verbose. Pass that parser as a parent anywhere you need those options. - Keep Subcommand Flags Local — Flags that only matter to one subcommand, such as
--retriesor--dry-run, should live only in the parser for that subcommand. Do not repeat them in the base parser. - Watch For Hidden Parents — Some helper functions wrap
ArgumentParsercreation and pass their own parents list. When tracking a conflict, inspect any helper that returns a parser so you see the full set of parents that feed into it.
Subparsers deserve the same care. Build them with clear flags and rely on shared parents for global options. That pattern keeps error messages readable and makes it easier to adjust flags over time without tripping over duplicate names.
Avoiding Hidden Conflicts With Pytest And Other Tools
Tools that sit on top of argparse such as pytest, custom test runners, and rich CLI wrappers often add their own command line options under the hood. When your code lives inside those tools, the full flag list is larger than what you see in your own parser.
The simplest way to see those extra options is to run the tool with a help flag and read the full options list. Any flag that appears there is off limits for new arguments in your own code unless you are fully replacing the tool’s parser with your own.
- Check The Host Tool Help Output — Run commands such as
pytest --helporyourtool --helpand scan for the flag string from your error message. If the host already shows that flag, pick a new name in your project. - Prefer Long, Descriptive Names — Short flags are easy to collide. Long names such as
--browser-nameor--session-timeoutare less likely to clash with existing options and are clearer for new users. - Keep Plugin Options Grouped — If you add options through plugin hooks, place the
addoption()calls in one place and reuse the same parser logic across the project. That way you can audit custom flags quickly whenever a conflict appears.
Quick scan — When a new version of a host tool lands, rerun its help output and compare it with your own flag list. A short review at upgrade time avoids surprises from new reserved flags that could collide with your custom options.
Quick Reference Table For Argparse Conflict Fixes
Use this table as a fast reminder of the main causes of the argparse argumenterror conflicting option string and the matching fix for each case.
| Symptom | Likely Cause | Typical Fix |
|---|---|---|
| Error mentions -h/–help | Built in help flag collides with a manual help option | Create parser with add_help=False and add your own help flag once |
| Error mentions a custom flag | Same option string used in more than one parser | Search for the flag text and keep only one definition or rename the duplicates |
| Error appears only with parents | Two parent parsers share a flag such as --config |
Move shared flags into a single base parent and keep subcommand flags local |
| Error appears inside a test or host tool | Tool or plugin already defines the same flag you added | Check host tool help output and pick a distinct long name for your custom flag |
| Error appears even after cleanup | You want newer flags to replace older ones by design | Create the parser with conflict_handler='resolve' so newer flags override |
Once you understand why argparse blocks duplicate option strings, the error stops feeling mysterious. You read the flag name from the message, trace where that string is defined, and then decide which parser should own it. With a single owner per flag and a quick scan of host tool options, your command line interface stays tidy and this error turns into a rare visitor instead of a daily annoyance.
