summary
Three URL-accepting CLI commands crash with a raw ValueError traceback instead of a clean error when given a malformed IPv6 URL (an unclosed bracket):
$ specify extension add my-ext --from "https://[::1/ext.zip" # extensions/_commands.py:429
$ specify preset add --from "https://[::1/preset.zip" # presets/_commands.py:107
$ specify workflow add "https://[::1/wf.yaml" # workflows/_commands.py:620
All three show a Rich traceback ending in ValueError: Invalid IPv6 URL raised from urllib.parse.urlparse.
root cause
Each site parses the user-supplied URL with a bare urlparse(...) before its HTTPS/host validation runs. urlparse raises ValueError on an unclosed IPv6 bracket, which escapes the command handler — the validation that would have produced a friendly error is never reached.
Same crash class as the bundle catalog add half of #3366 (fixed in #3367 for the bundler config path); these are the remaining direct CLI entry points where argv flows into an unguarded urlparse.
impact
Cosmetic-to-DX severity: no wrong behavior is persisted, but a typo in a URL argument produces a full traceback instead of the clean [red]Error:[/red] message every neighboring validation failure gets.
proposed fix
Wrap the urlparse call at each of the three sites in try/except ValueError and emit the same style of clean error + typer.Exit(1) the surrounding validation uses. I have a patch with one regression test per command ready and can open a PR.
summary
Three URL-accepting CLI commands crash with a raw
ValueErrortraceback instead of a clean error when given a malformed IPv6 URL (an unclosed bracket):All three show a Rich traceback ending in
ValueError: Invalid IPv6 URLraised fromurllib.parse.urlparse.root cause
Each site parses the user-supplied URL with a bare
urlparse(...)before its HTTPS/host validation runs.urlparseraisesValueErroron an unclosed IPv6 bracket, which escapes the command handler — the validation that would have produced a friendly error is never reached.Same crash class as the
bundle catalog addhalf of #3366 (fixed in #3367 for the bundler config path); these are the remaining direct CLI entry points where argv flows into an unguardedurlparse.impact
Cosmetic-to-DX severity: no wrong behavior is persisted, but a typo in a URL argument produces a full traceback instead of the clean
[red]Error:[/red]message every neighboring validation failure gets.proposed fix
Wrap the
urlparsecall at each of the three sites intry/except ValueErrorand emit the same style of clean error +typer.Exit(1)the surrounding validation uses. I have a patch with one regression test per command ready and can open a PR.