[GH-ISSUE #7440] [Bug] search --format md hides allowed enum values in rendered argument errors #4445

Closed
opened 2026-10-31 00:49:51 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 27, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/7440

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI

Observed behavior

An invalid search --kind invocation selects Markdown successfully but leaves the separator between allowed values unescaped inside its diagnostic table. The raw output contains both strings and procedures; rendering it with the repository's locked VitePress renderer displays only strings in the message cell. The valid procedures alternative disappears. The command correctly exits 1 with VALIDATION_ERROR and empty stderr.

Reproduction

  1. Start at the built baseline checkout with its locked dependencies installed and Node 24.22.1 available as node. Select the executable, then enter an empty directory and isolate HOME:
REA_ENTRY="$PWD/scripts/rea.mjs"
probe_dir="$(mktemp -d)"
cd "$probe_dir"
mkdir home
  1. Run the following exact invocation. No target fixture is required because argument validation fails before opening the missing input:
HOME="$PWD/home" node "$REA_ENTRY" search ./missing-input needle --kind unrecognized --format md
printf 'exit=%s\n' "$?"

Observed output:

## code

VALIDATION_ERROR

## message

REA could not read the command arguments. Check the named argument and its expected type, then try again.

## fieldErrors

| code          | missing | path | expected | received | message                                                |
|---------------|---------|------|----------|----------|--------------------------------------------------------|
| invalid_value | false   | kind |          |          | Invalid option: expected one of "strings"|"procedures" |
exit=1
  1. Compare the JSON diagnostic using the same input:
HOME="$PWD/home" node "$REA_ENTRY" search ./missing-input needle --kind unrecognized --format json
printf 'exit=%s\n' "$?"

The observed JSON retains fieldErrors[0].message as Invalid option: expected one of "strings"|"procedures" and exits 1. The Markdown failure reproduced on all three attempts; both JSON control attempts preserved the complete message. Two of those Markdown outputs were independently rendered with locked VitePress, and both lost procedures from the visible message cell.

Expected behavior

Under “Output and exit status”, docs/cli.md, lines 965–967, promises: “--format md escapes backslashes, pipes, and inline Markdown syntax in table headers and cells so source text is displayed literally, and renders cell line breaks as <br>.” This paragraph does not exclude argument-validation diagnostics. The fieldErrors table emitted for the selected format should display both allowed values literally within its existing message column, while retaining input rejection and exit 1.

Impact and scope

The rendered error omits a valid option that the caller needs to correct the invocation. A second observed command, doctor --client 'x|y' --format md, also exited 1 and rendered only the first of 26 allowed client names; the other 25 alternatives disappeared. That command was run once. Its input pipe is not echoed: the unescaped separators come from the generated allowed-value list. JSON preserved the full search diagnostic and is an observed workaround. Reading raw Markdown also retains the source text. Other commands, renderers and platforms were not tested. No stored Evidence loss or target modification was observed.

REA version

6.8.0 (source commit a905a71e31)

Runtime and platform

Node 24.22.1; macOS 27.0.1 arm64; locked VitePress 1.6.4.

Target and artifact context

Not applicable: the failing commands stop during argument validation and require no target, provider or external API.

Interface

CLI

Earliest failure stage

Request parsing or validation

Relevant output or evidence

Observed through the built public executable, with HOME redirected into a fresh scratch directory. The search table has six header fields but seven raw data fields because its message contains an unescaped delimiter. VitePress renders six cells and discards the surplus field, rather than displaying seven columns. The renderer's message cell was:

<td>Invalid option: expected one of &quot;strings&quot;</td>

The same rendering comparison on doctor retained only Invalid option: expected one of "claude_code". A separate observed inspect-byte-entropy './pi|pe.bin' --format md control, using an inline three-byte file, escaped the pipe in its result table cells and exited 0. This establishes that command-result Markdown and pre-execution diagnostics behave differently; it does not establish that all other result or error paths are correct.

Source-only trace (not instrumented): src/cli.ts:168 installs the result wrapper and src/cli.ts:170 installs argument guidance. src/cli/cliResultOutput.ts:75 wraps command execution; src/cli/argumentErrors.ts:18 preserves the parser's fieldErrors when replacing its top-level guidance. Incur parses before calling command.run at node_modules/incur/dist/internal/command.js:26 and emits fieldErrors at node_modules/incur/dist/Cli.js:1396. Its table formatter interpolates cell text without escaping at node_modules/incur/dist/Formatter.js:49. REA's escaping owner is src/cli/cliOutputFormatter.ts:61; the Markdown parser-diagnostic path bypasses it. src/cli/cliResultOutput.ts:229 captures SDK output only for JSONL, and scripts/rea.mjs:150 forwards the remaining SDK output.

Typed outcome or recovery expected

Keep VALIDATION_ERROR, the argument guidance, the field coordinates and exit 1. Escape the diagnostic's literal pipe so the rendered message preserves the complete allowed-value list within one column. Keep JSON diagnostic values unchanged.

Analysis or suspected cause

Source-only (not executed as an instrumented trace): REA owns Markdown escaping around registered command results, while parser failures occur before that result wrapper executes. The separate Incur error formatter constructs the diagnostic table directly. Routing only successful command data through REA's formatter therefore leaves this earlier diagnostic surface with different escaping behavior.

Additional context

Related (closed):
https://github.com/morluto/rea/issues/6755

That report repaired raw pipes in retained command-result data; its fixing commit is already an ancestor of this baseline, but the independently reproduced parser-diagnostic path still emits unescaped enum separators. The currently open provider-cell report concerns VitePress handling of nested JSON in successful capabilities output and has a different restoration check. No open exact duplicate was found. The npm version query returned 6.8.0; the published package was not separately executed.

Originally created by @coygeek on GitHub (Oct 27, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7440 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI ### Observed behavior An invalid `search --kind` invocation selects Markdown successfully but leaves the separator between allowed values unescaped inside its diagnostic table. The raw output contains both `strings` and `procedures`; rendering it with the repository's locked VitePress renderer displays only `strings` in the message cell. The valid `procedures` alternative disappears. The command correctly exits 1 with `VALIDATION_ERROR` and empty stderr. ### Reproduction 1. Start at the built baseline checkout with its locked dependencies installed and Node 24.22.1 available as `node`. Select the executable, then enter an empty directory and isolate HOME: ```sh REA_ENTRY="$PWD/scripts/rea.mjs" probe_dir="$(mktemp -d)" cd "$probe_dir" mkdir home ``` 2. Run the following exact invocation. No target fixture is required because argument validation fails before opening the missing input: ```sh HOME="$PWD/home" node "$REA_ENTRY" search ./missing-input needle --kind unrecognized --format md printf 'exit=%s\n' "$?" ``` Observed output: ```text ## code VALIDATION_ERROR ## message REA could not read the command arguments. Check the named argument and its expected type, then try again. ## fieldErrors | code | missing | path | expected | received | message | |---------------|---------|------|----------|----------|--------------------------------------------------------| | invalid_value | false | kind | | | Invalid option: expected one of "strings"|"procedures" | exit=1 ``` 3. Compare the JSON diagnostic using the same input: ```sh HOME="$PWD/home" node "$REA_ENTRY" search ./missing-input needle --kind unrecognized --format json printf 'exit=%s\n' "$?" ``` The observed JSON retains `fieldErrors[0].message` as `Invalid option: expected one of "strings"|"procedures"` and exits 1. The Markdown failure reproduced on all three attempts; both JSON control attempts preserved the complete message. Two of those Markdown outputs were independently rendered with locked VitePress, and both lost `procedures` from the visible message cell. ### Expected behavior Under “Output and exit status”, docs/cli.md, lines 965–967, promises: “`--format md` escapes backslashes, pipes, and inline Markdown syntax in table headers and cells so source text is displayed literally, and renders cell line breaks as `<br>`.” This paragraph does not exclude argument-validation diagnostics. The fieldErrors table emitted for the selected format should display both allowed values literally within its existing message column, while retaining input rejection and exit 1. ### Impact and scope The rendered error omits a valid option that the caller needs to correct the invocation. A second observed command, `doctor --client 'x|y' --format md`, also exited 1 and rendered only the first of 26 allowed client names; the other 25 alternatives disappeared. That command was run once. Its input pipe is not echoed: the unescaped separators come from the generated allowed-value list. JSON preserved the full search diagnostic and is an observed workaround. Reading raw Markdown also retains the source text. Other commands, renderers and platforms were not tested. No stored Evidence loss or target modification was observed. ### REA version 6.8.0 (source commit a905a71e31f71457cb21fd056b234f872126974e) ### Runtime and platform Node 24.22.1; macOS 27.0.1 arm64; locked VitePress 1.6.4. ### Target and artifact context Not applicable: the failing commands stop during argument validation and require no target, provider or external API. ### Interface CLI ### Earliest failure stage Request parsing or validation ### Relevant output or evidence Observed through the built public executable, with HOME redirected into a fresh scratch directory. The search table has six header fields but seven raw data fields because its message contains an unescaped delimiter. VitePress renders six cells and discards the surplus field, rather than displaying seven columns. The renderer's message cell was: ```html <td>Invalid option: expected one of &quot;strings&quot;</td> ``` The same rendering comparison on `doctor` retained only `Invalid option: expected one of "claude_code"`. A separate observed `inspect-byte-entropy './pi|pe.bin' --format md` control, using an inline three-byte file, escaped the pipe in its result table cells and exited 0. This establishes that command-result Markdown and pre-execution diagnostics behave differently; it does not establish that all other result or error paths are correct. Source-only trace (not instrumented): `src/cli.ts:168` installs the result wrapper and `src/cli.ts:170` installs argument guidance. `src/cli/cliResultOutput.ts:75` wraps command execution; `src/cli/argumentErrors.ts:18` preserves the parser's fieldErrors when replacing its top-level guidance. Incur parses before calling command.run at `node_modules/incur/dist/internal/command.js:26` and emits fieldErrors at `node_modules/incur/dist/Cli.js:1396`. Its table formatter interpolates cell text without escaping at `node_modules/incur/dist/Formatter.js:49`. REA's escaping owner is `src/cli/cliOutputFormatter.ts:61`; the Markdown parser-diagnostic path bypasses it. `src/cli/cliResultOutput.ts:229` captures SDK output only for JSONL, and `scripts/rea.mjs:150` forwards the remaining SDK output. ### Typed outcome or recovery expected Keep `VALIDATION_ERROR`, the argument guidance, the field coordinates and exit 1. Escape the diagnostic's literal pipe so the rendered message preserves the complete allowed-value list within one column. Keep JSON diagnostic values unchanged. ### Analysis or suspected cause Source-only (not executed as an instrumented trace): REA owns Markdown escaping around registered command results, while parser failures occur before that result wrapper executes. The separate Incur error formatter constructs the diagnostic table directly. Routing only successful command data through REA's formatter therefore leaves this earlier diagnostic surface with different escaping behavior. ### Additional context Related (closed): https://github.com/morluto/rea/issues/6755 That report repaired raw pipes in retained command-result data; its fixing commit is already an ancestor of this baseline, but the independently reproduced parser-diagnostic path still emits unescaped enum separators. The currently open provider-cell report concerns VitePress handling of nested JSON in successful capabilities output and has a different restoration check. No open exact duplicate was found. The npm version query returned 6.8.0; the published package was not separately executed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4445
No description provided.