argparse: unrecognized arguments / arguments are required (tested)
error: the following arguments are required and error: unrecognized arguments are argparse's two most common exits. We measured both, plus how to collect, catch or avoid them, on Python 3.13.5.
1. Both errors, from the same script
The script, cli.py:
import argparse
p = argparse.ArgumentParser(prog="cli.py")
p.add_argument("path")
p.add_argument("--verbose", action="store_true")
print(p.parse_args())
python3 cli.py; echo "exit code: $?"
python3 cli.py data.txt --verbos; echo "exit code: $?"
python3 cli.py data.txt extra.txt; echo "exit code: $?"
Output:
usage: cli.py [-h] [--verbose] path
cli.py: error: the following arguments are required: path
exit code: 2
Namespace(path='data.txt', verbose=True)
exit code: 0
usage: cli.py [-h] [--verbose] path
cli.py: error: unrecognized arguments: extra.txt
exit code: 2
Measured on Python 3.13.5: a missing positional gives the following arguments are required: path; an extra one gives unrecognized arguments: extra.txt. Both print the usage line and exit with code 2. And note the middle run: --verbos (a typo) was accepted as --verbose, because argparse allows unambiguous prefixes by default. Pass allow_abbrev=False to ArgumentParser if you want typos rejected.
2. Unknown arguments you want to keep: parse_known_args()
import argparse, sys
p = argparse.ArgumentParser(prog="tool")
p.add_argument("--n", type=int)
sys.argv = ["tool", "--n", "3", "--fast"]
args, rest = p.parse_known_args() # keep unknown args instead of exiting
print(args, rest)
Output:
Namespace(n=3) ['--fast']
Measured: parse_known_args() returns the parsed namespace plus a list of what it didn't recognize, instead of exiting. Useful when passing flags through to another program.
3. In Jupyter, IPython or pytest: pass the list yourself
import argparse
p = argparse.ArgumentParser(prog="tool")
p.add_argument("--n", type=int)
# in Jupyter/IPython/pytest, sys.argv holds the host's own flags; pass a list explicitly
print(p.parse_args([]))
print(p.parse_args(["--n", "5"]))
Output:
Namespace(n=None)
Namespace(n=5)
parse_args() with no argument reads sys.argv[1:], which in a notebook kernel or test runner holds that program's flags (for example the kernel's -f connection file), so you get unrecognized arguments for flags you never typed. Pass an explicit list, as above ([] for defaults).
4. Catch it instead of exiting: exit_on_error=False
import argparse
p = argparse.ArgumentParser(prog="tool", exit_on_error=False)
p.add_argument("path")
for argv in (["a", "b"], []):
try:
print(p.parse_args(argv))
except argparse.ArgumentError as e:
print("ArgumentError:", e)
except SystemExit as e:
print("still SystemExit", e.code)
Output:
ArgumentError: unrecognized arguments: b
ArgumentError: the following arguments are required: path
Measured on 3.13.5: with exit_on_error=False, both errors raise argparse.ArgumentError you can catch. We did not test older versions, where this flag has had gaps; if you need to support them, also catch SystemExit.
5. Making an argument optional (or an option required)
import argparse
p = argparse.ArgumentParser(prog="tool")
p.add_argument("path", nargs="?", default="input.txt") # optional positional
p.add_argument("--out", required=True) # required option
print(p.parse_args(["--out", "o.txt"]))
try:
p.parse_args([])
except SystemExit as e:
print("exit", e.code)
Output:
Namespace(path='input.txt', out='o.txt')
usage: tool [-h] --out OUT [path]
tool: error: the following arguments are required: --out
exit 2
Measured: nargs="?" with a default makes a positional optional. The reverse also exists: required=True on an option gives the same "the following arguments are required: --out" error when it's missing.
Frequently asked questions
How do I fix argparse error: the following arguments are required?
Pass the positional argument on the command line, or make it optional with nargs='?' and a default. We measured both on Python 3.13.5.
How do I fix argparse error: unrecognized arguments?
Remove the extra argument, declare it with add_argument, or use parse_known_args() to collect unknown ones. In Jupyter or pytest, call parse_args([]) with an explicit list.
Why does argparse accept a misspelled option?
allow_abbrev is on by default, so unambiguous prefixes match. We measured --verbos being accepted as --verbose. Use ArgumentParser(allow_abbrev=False).
How do I stop argparse from exiting on error?
ArgumentParser(exit_on_error=False) raises argparse.ArgumentError instead; we measured that for both errors on Python 3.13.5.
Written with AI assistance. Measured on 2026-10-09 with Python 3.13.5 on Linux: missing and extra positionals and their exit code, prefix matching of a misspelled option, parse_known_args, explicit argument lists, exit_on_error=False, nargs='?' and required options. Every block was run verbatim and its output pasted from that run. Older Python versions were not tested. PlainHeaders is our extension; everything else here is the standard library.