Skip to content

Fix options being dropped when a parameter description is multi-line#9

Open
enricodelazzari wants to merge 1 commit into
spatie:mainfrom
enricodelazzari:fix/sanitize-multiline-parameter-descriptions
Open

Fix options being dropped when a parameter description is multi-line#9
enricodelazzari wants to merge 1 commit into
spatie:mainfrom
enricodelazzari:fix/sanitize-multiline-parameter-descriptions

Conversation

@enricodelazzari

Copy link
Copy Markdown

Problem

When an OpenAPI parameter has a multi-line description (free-form Markdown, which is perfectly valid per the spec), the generated command throws at runtime as soon as it's executed:

The "order" option does not exist.

Root cause

EndpointCommand::buildSignature() interpolates the raw description into Laravel's signature DSL:

$parts[] = "{--{$optionName}= : {$description}}";

Laravel's signature parser extracts tokens with preg_match_all('/\{\s*(.*?)\s*\}/', ...)no s modifier, so . doesn't match newlines. A {--order= : line1\n\nline2} block is therefore never matched, and the option is silently dropped (it doesn't even show up in --help).

But buildSignature() still records the parameter in $queryParamOptionMap / $pathParamOptionMap. At runtime buildRequestUrl() iterates that map and calls $this->option($name) on the option that was never registered → InvalidOptionException.

This breaks every endpoint whose parameters have multi-line descriptions ({/} in a description hit the same problem).

Minimal reproduction

[$name, $args, $opts] = Illuminate\Console\Parser::parse("cmd {--order= : One line}");
// → option --order registered

[$name, $args, $opts] = Illuminate\Console\Parser::parse("cmd {--order= : One line.\n\nTwo lines.}");
// → NO options registered

Fix

Sanitize the description before embedding it in the signature: collapse whitespace runs (including newlines) into single spaces and strip {/}.

Tests

Added a regression test in QueryParametersTest that registers a query parameter with a multi-line description and asserts the command runs and sends the parameter. It fails on main with the exact The "--order" option does not exist. error and passes with the fix.

Full suite (348 tests) green; Pint passes. (The 2 pre-existing PHPStan errors at EndpointCommand.php:49 are unrelated to this change.)

🤖 Generated with Claude Code

Command signatures are a single-line mini-language in which `{`, `}` and
newlines are significant. OpenAPI parameter descriptions are free-form
Markdown and may legitimately span multiple lines, so embedding them raw
into the signature caused Laravel's signature parser (whose token regex
has no `s` modifier) to silently skip the whole `{--option= : ...}` block.

The option was therefore never registered, yet it remained in the
path/query option map, so building the request URL called
`$this->option($name)` on an undefined option and threw
`The "<name>" option does not exist.` at runtime.

Sanitize descriptions (collapse whitespace, strip braces) before placing
them in the signature.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant