Missing argument handling
Why it matters
When a required argument is silently missing, the command either crashes mid-execution with a raw TypeError: Cannot read properties of undefined — dumping a stack trace onto the user — or it runs with undefined as a value and produces silent corruption downstream (a deploy target of undefined, a file named undefined.json, a database query with a null key). CWE-233 (Improper Handling of Parameters) applies: the input is invalid, but no validation gate catches it before execution begins. ISO 25010:2011 usability.learnability penalizes CLIs that make users guess what went wrong — the error message must name the missing argument and show the correct usage.
Severity rationale
High because missing required arguments that produce TypeErrors or silent `undefined` behavior give users no actionable path to recovery without reading source code.
Remediation
Use the framework's native required-argument syntax so validation happens before your handler runs. In commander, angle brackets mark required arguments:
program
.command('deploy <target>')
.description('Deploy to the specified target')
.action((target) => {
// commander errors automatically: "error: missing required argument 'target'"
deploy(target)
})
In click, arguments are required by default:
@cli.command()
@click.argument('target') # required — click handles: "Error: Missing argument 'TARGET'."
def deploy(target):
"""Deploy to the specified TARGET."""
pass
Never access argv[n] or opts.target without first confirming the value is defined — opt into your framework's built-in validation rather than writing manual if (!target) guards that are easy to miss.
Detection
-
ID:
missing-arg-handling -
Severity:
high -
What to look for: List all required arguments across every command. For each, check what happens when required arguments are omitted. In commander, verify
.argument('<required>')or.requiredOption()are used (not just.argument('optional')). Check that the framework's built-in validation is active. If custom validation exists, verify it produces helpful messages. Test the pattern: what happens if the user runsmytool deploywhendeploy <target>is expected? -
Pass criteria: Omitting a required argument produces a specific error naming the missing argument and showing the correct usage. The framework's built-in required argument validation is active, or equivalent custom validation exists — 100% of missing required arguments must produce a specific error message naming the missing argument. Report: "X required arguments found, all Y produce clear errors when missing."
-
Fail criteria: Missing required arguments cause an unhandled exception (TypeError, undefined reference), a silent failure (command runs with undefined values), or a generic error that doesn't name the missing argument.
-
Skip (N/A) when: The CLI has no required arguments — all arguments are optional or have defaults. All checks skip when no CLI entry point is detected.
-
Detail on fail:
"Running 'mytool deploy' without target argument causes TypeError: Cannot read properties of undefined — the required argument is accessed but not validated"or"Missing required argument silently uses 'undefined' as the value — deploy proceeds with undefined target" -
Remediation: Required arguments must be validated before the command handler runs:
// commander — use angle brackets for required args program .command('deploy <target>') .description('Deploy to the specified target') .action((target) => { // commander will error automatically if target is missing: // "error: missing required argument 'target'" deploy(target) })# click — arguments are required by default @cli.command() @click.argument('target') # required by default, click handles the error def deploy(target): """Deploy to the specified TARGET.""" pass
External references
- cwe · CWE-233 — Improper Handling of Parameters
- iso-25010:2011 · usability.learnability — Usability — Learnability
Taxons
History
- 2026-04-18·v1.0.0·Initial import from cli-quality·automated