argparse suggest_on_error: Better CLI Errors

Published on: September 18, 2026
Reading time: 5 minutes
Command-line terminal used by a Python argparse application

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.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Code and file structure for Python Zstandard compression
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Compress Data with Zstandard

    Learn how to compress and decompress data with Python compression.zstd using streams, dictionaries, limits, and safe workflows.

    Ler mais

    Tempo de leitura: 5 minutos
    18/09/2026
    Programmer managing an asynchronous queue with Python asyncio.Queue.shutdown
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Queue.shutdown: Shut Down Queues Safely

    Learn Python asyncio.Queue.shutdown to close queues, release workers, drain tasks, and prevent deadlocks in asynchronous pipelines.

    Ler mais

    Tempo de leitura: 5 minutos
    17/09/2026
    Debugging a running Python process with pdb -p
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python pdb -p: Debug Running Processes

    Learn how to use Python pdb -p to attach to running processes, inspect stacks, diagnose hangs, and debug production incidents

    Ler mais

    Tempo de leitura: 6 minutos
    17/09/2026
    Python code processed in batches with itertools.batched
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    itertools.batched strict: Validate Complete Batches

    Learn Python itertools.batched with strict mode to build batches, validate complete groups, and process streams safely.

    Ler mais

    Tempo de leitura: 5 minutos
    16/09/2026
    Data analysis and calculations with Python math.sumprod
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    math.sumprod: Dot Products and Weighted Averages

    Learn Python math.sumprod for dot products, weighted averages, costs, scores, and clear numeric calculations.

    Ler mais

    Tempo de leitura: 4 minutos
    16/09/2026
    CSV data analysis with Python csv.QUOTE_STRINGS
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    csv.QUOTE_STRINGS: Preserve Types in CSV Files

    Learn Python csv.QUOTE_STRINGS to quote text, preserve types, and build more predictable and secure CSV files.

    Ler mais

    Tempo de leitura: 4 minutos
    15/09/2026