oclif / oclif/plugin-not-found
command_not_found: accepting a suggestion for a command with a required arg leaks stack traces + a spurious "command not found"
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 17
- Forks
- 10
- Avg merge
- 24m
- Merged PRs (30d)
- 2
Description
Describe the bug
When the command_not_found hook offers a "did you mean …?" suggestion and the user accepts, the hook re-runs the suggested command via this.config.runCommand(suggestion, argv) (src/index.ts). If that suggested command then fails a showHelp parse error (e.g. a missing required arg, RequiredArgsError, or an unexpected flag), the user is shown two raw stack traces instead of a clean error.
The root of the mis-render is in @oclif/core's top-level handle(), which renders showHelp-flagged errors with showHelp(process.argv.slice(2)). Because the failure surfaces from inside the hook, process.argv still holds the original, unknown command the user typed — not the suggested command that actually ran. showHelp can't resolve the original id, throws Command <typo> not found., and that lands in handle()'s emergency catch, which dumps err.stack followed by error.stack.
The same RequiredArgsError renders cleanly when the command is invoked directly, so the regression is specific to the suggestion-acceptance flow.
To Reproduce
A minimal CLI repro with a single command greet NAME (NAME required) and this plugin installed:
- Run
repro gree(a typo ofgreet). - At
Warning: gree is not a repro command. Did you mean greet? [y/n], answery. greetruns with no args and fails required-arg validation.- Output (note the two stack traces + the spurious final line):
› Warning: gree is not a repro command.
› Error: Missing 1 required arg:
› name who to greet
› See more help with --help
Error: Missing 1 required arg:
name who to greet
See more help with --help
at validateArgs (.../@oclif/core/lib/parser/validate.js:84:19)
...
at async Config.runHook (.../@oclif/core/lib/config/config.js:524:9)
Error: Command gree not found.
at error (.../@oclif/core/lib/errors/error.js:44:15)
at Help.showHelp (.../@oclif/core/lib/help/index.js:269:27)
at handle (.../@oclif/core/lib/errors/handle.js:46:28)
Contrast — running the suggested command directly, repro greet, produces the expected clean output (pretty error + USAGE/ARGUMENTS, no stack trace, no "not found").
Expected behavior
Accepting a suggestion should render the suggested command's parse error exactly as if it had been typed directly: the pretty message plus its usage/help, with no raw stack traces and no spurious "Command not found."
Environment (please complete the following information):
@oclif/plugin-not-found3.2.93@oclif/core4.13.3- OS & version: macOS 15 (Darwin 25.4.0)
- Shell/terminal & version: zsh
- Node: v24.15.0
Additional context
The trigger is any showHelp-flagged parse error on the re-run: RequiredArgsError, UnexpectedArgsError, and NonExistentFlagsError all set showHelp = true. The underlying process.argv mismatch is in @oclif/core's handle() (showHelp(process.argv.slice(2)) vs. err.parse.input.argv), but it's only reachable in practice through this hook re-running a different command than the one the user typed. Two options: this plugin could catch/normalize the error from the re-run before it reaches handle(), and/or @oclif/core could render showHelp against err.parse.input.argv rather than process.argv.
I have a self-contained reproduction (fixture CLI + failing-vs-clean tests) and am happy to open a PR.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the self-contained fixture and failing-versus-clean tests, then inspect the suggestion re-run in src/index.ts and @oclif/core's top-level handle(). Reproduce the required-argument case and check the related unexpected-argument and nonexistent-flag cases. Done means accepted suggestions show the same clean parse error and help as direct invocation, without stack traces or a spurious command-not-found error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100