Skip to content

fix(parser): preserve full option string in short-option error messages#3421

Closed
algojogacor wants to merge 1 commit into
pallets:mainfrom
algojogacor:fix/issue-2779-short-option-error-msg
Closed

fix(parser): preserve full option string in short-option error messages#3421
algojogacor wants to merge 1 commit into
pallets:mainfrom
algojogacor:fix/issue-2779-short-option-error-msg

Conversation

@algojogacor
Copy link
Copy Markdown

Summary

Fixes #2779 — When a user passes an invalid multi-character single-dash option like -dbgwrong, Click now shows the full original token in the error message with close-match suggestions (e.g. No such option '-dbgwrong'. Did you mean '-dbg'?) instead of the confusing single-character error (No such option: -d).

Root Cause

In src/click/parser.py, the _match_short_opt method (line 390) iterates character-by-character over a single-dash argument. When a character is not found in _short_opt, it raises NoSuchOption(opt, ...) where opt is the single-character option like -d (line 405). This is technically correct for POSIX-style stacked short options (-abc = -a -b -c), but produces a confusing error when the user intended the entire token as a single option name (e.g. -dbgwrong is a typo for -dbg).

The specific mechanism:

  1. _process_opts receives -dbgwrong, tries _match_long_opt which fails (no exact match for -dbgwrong)
  2. Falls through to _match_short_opt which processes d, b, g...
  3. d is not a registered short option → raises NoSuchOption(-d) — confusing!

Fix

In _match_short_opt, when the first character after the prefix is not a registered short option (i == 2), raise NoSuchOption with the full original arg string and include _long_opt possibilities for get_close_matches suggestions. When a later character fails (genuine stacking error like -abZ where -a and -b are valid but -Z is not), keep the existing per-character diagnostic.

if i == 2:
    raise NoSuchOption(arg, possibilities=self._long_opt, ctx=self.ctx)
raise NoSuchOption(opt, ctx=self.ctx)

Changes

  • src/click/parser.py (lines 405-415): Added conditional in _match_short_opt to detect first-character failure and raise with the full original argument + long-option suggestions.

Testing

  • All 1492 existing tests pass (no regressions)
  • Manually verified:
    • -dbgwrong with -dbg defined → No such option '-dbgwrong'. Did you mean '-dbg'?
    • -xinvalid with -d defined → No such option '-xinvalid'.
    • -abZ with -a/-b defined (stacking, later char unknown) → No such option '-Z'. (per-char preserved) ✓
    • -ab stacking with -a/-b defined → works correctly ✓
    • --debgu typo suggestion → No such option '--debgu'. Did you mean '--debug'?

When a user passes an invalid multi-character single-dash option like
'-dbgwrong', Click's parser splits it character-by-character as stacked
short options and raises NoSuchOption with only the first unmatched
single character (e.g. '-d'), producing the confusing error message
'No such option: -d'.

This happens because _match_short_opt iterates over each character after
the prefix and raises NoSuchOption with the single-char opt when a
character is not found.  When the very first character of the token
fails to match, the user most likely intended the entire token as a
single option name (e.g. -dbgwrong is a typo for -dbg).

Fix: When the first character (i == 2) is not a registered short option,
raise NoSuchOption with the full original argument string and include
_long_opt possibilities for close-match suggestions.  When a later
character fails (genuine stacking error), keep the per-character
diagnostic unchanged.

Now '-dbgwrong' produces: No such option '-dbgwrong'. Did you mean '-dbg'?
instead of: No such option: -d.

Fixes pallets#2779
@davidism
Copy link
Copy Markdown
Member

AI junk, didn't read the linked discussion.

@davidism davidism closed this May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wrong error message when wrong multicharacter short option is passed

2 participants