Command-line tools live or die by the quality of their feedback. A user who mistypes a command should not need to search the documentation just to discover one missing letter. Python’s argparse module addresses this with suggest_on_error, an option that can add a likely correction when an invalid textual choice is entered. This guide explains how the feature works, where it is useful, how to keep compatibility with older Python versions, and how to design clearer and safer command-line interfaces around it.
What suggest_on_error does
argparse is Python’s standard library module for parsing command-line arguments. Traditionally, an invalid value produces an error listing the accepted choices. When suggest_on_error=True is enabled, the parser can compare the invalid text with known string choices and show a close match.
import argparse
parser = argparse.ArgumentParser(suggest_on_error=True)
parser.add_argument("action", choices=["start", "stop", "restart"])
args = parser.parse_args()
print(args.action)
If a user enters restar, the error may point to restart. The parser still rejects the command. It does not silently replace the input, which is important for predictable and secure behavior.
Why better CLI errors matter
Command-line applications are often used in deployment jobs, data pipelines, remote servers, scheduled tasks, and development workflows. In those environments, the error message is part of the product interface. A vague message creates friction, while a relevant suggestion lets the user recover immediately.
This concern belongs to a broader set of Python design practices. You can study Python contextlib.ExitStack for dynamic resource cleanup, Python typing.override for safer inheritance contracts, Python string.Template for configurable messages, and Python TopologicalSorter for dependency-aware workflows.
Version compatibility
suggest_on_error is a recent addition. Passing it directly to ArgumentParser on an older interpreter may raise TypeError. Applications that control their runtime can simply declare the required Python version. Libraries and reusable tools may need a compatibility path.
import argparse
parser = argparse.ArgumentParser()
if hasattr(parser, "suggest_on_error"):
parser.suggest_on_error = True
Feature detection is often better than comparing version strings because it checks the actual capability available at runtime. Document the minimum supported version and include tests for every interpreter your package claims to support.
Using suggestions with choices
The clearest use case is an argument with string choices:
parser = argparse.ArgumentParser(suggest_on_error=True)
parser.add_argument(
"environment",
choices=["development", "staging", "production"]
)
A value such as prodution is close enough to production to produce a useful recommendation. Suggestions work best with readable strings. Numeric values, opaque identifiers, and custom objects do not provide the same experience because textual similarity may be meaningless.
Subcommands and CLI structure
Large tools commonly use subcommands such as deploy, rollback, status, and logs. Suggestions can help with small spelling errors, but they cannot repair an inconsistent command taxonomy. Use verbs consistently, avoid unnecessary abbreviations, and keep related commands easy to predict.
parser = argparse.ArgumentParser(suggest_on_error=True)
subparsers = parser.add_subparsers(dest="command", required=True)
subparsers.add_parser("deploy")
subparsers.add_parser("rollback")
subparsers.add_parser("status")
Good naming remains the developer’s responsibility. The feature improves recovery after a typo; it does not replace thoughtful interface design.
Combine it with useful help text
Every argument should have concise help text describing what it controls, its expected format, and any meaningful default. Add a description to the parser, examples in the epilog, and metavar values when they improve readability. For domain-specific validation, define a custom type and raise argparse.ArgumentTypeError.
from pathlib import Path
import argparse
def existing_file(value: str) -> Path:
path = Path(value)
if not path.is_file():
raise argparse.ArgumentTypeError(f"File not found: {value}")
return path
parser = argparse.ArgumentParser(suggest_on_error=True)
parser.add_argument("--config", type=existing_file)
Here, the suggestion feature and custom validation solve different problems. One handles close textual matches among known choices; the other enforces a real application rule.
Testing error suggestions
Error behavior is part of your public interface and should be tested. With pytest, call the parser with invalid arguments, expect SystemExit, and capture standard error.
import pytest
def test_invalid_choice(parser, capsys):
with pytest.raises(SystemExit):
parser.parse_args(["prodution"])
captured = capsys.readouterr()
assert "production" in captured.err
Avoid asserting the entire error message unless your project intentionally guarantees exact wording. Python versions may adjust punctuation or formatting. Test the important semantic elements: the rejected value, the expected alternative, and the exit behavior.
Security considerations
Never automatically execute a suggested command. A recommendation is a usability hint, not authorization to change the user’s intent. This matters most for destructive operations such as deleting files, applying database migrations, modifying cloud infrastructure, or sending payments.
Keep invalid input invalid. For sensitive actions, add explicit confirmation, dry-run support, audit logs, least-privilege credentials, and clear summaries before execution. The official argparse documentation describes parser behavior, while the What’s New in Python documentation helps you verify when recent features became available.
When the feature is most valuable
Enable suggest_on_error when your CLI has several textual choices, many subcommands, or users who may not know every exact spelling. It is particularly helpful in deployment tools, package managers, code generators, administration utilities, and data-processing applications.
The benefit is smaller for parsers dominated by numbers, file paths, UUIDs, or free-form text. Those inputs need validation and examples rather than spelling suggestions.
Common design mistakes
Do not create dozens of nearly identical choices. Similar names can make suggestions ambiguous and make the interface difficult to learn. Do not rely on suggestions instead of documenting commands. Do not hide required version information. Finally, do not parse arguments deep inside business logic; keep parsing near the application boundary and pass validated values into testable functions.
Practical checklist
Use clear command names, declare string choices when the domain is closed, enable suggestions on supported runtimes, provide compatibility handling where necessary, write focused help text, validate domain rules separately, and test invalid inputs. For destructive commands, preserve explicit confirmation and never accept a fuzzy match automatically.
Conclusion
argparse suggest_on_error is a small feature with a meaningful usability payoff. It helps users recover from ordinary typing mistakes while preserving strict validation. Combined with consistent naming, useful help, version-aware code, and responsible safety checks, it can make a Python CLI feel substantially more polished and reliable.







