[GH-ISSUE #7554] [Bug] Browser scenario launch errors omit the executable and startup failure reason #4492

Closed
opened 2026-10-31 00:50:15 +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/7554

Before submitting

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

Area

Process capture or runtime observation

Observed behavior

Running node scripts/rea.mjs capture-browser-scenario "$scenario" --json with a launch-mode scenario returns the same generic execution_failure for two distinct host conditions: the selected executable exits immediately with a diagnostic on stderr, or that executable no longer exists. Neither response identifies the selected executable or explains its startup failure. Both tell the caller to run rea doctor and review details that contain no launch diagnosis.

This was observed through the built public CLI. Debug logging also omitted the path and startup reason. No real browser or GUI application was launched.

Reproduction

  1. From the built baseline checkout, with Node 24.22.1 on PATH, create an inert executable and a schema-valid scenario:
work_dir=$(mktemp -d)
mkdir -p "$work_dir"/{home,config,data,cache,state,tmp}
cat > "$work_dir/fake-browser" <<'SH'
#!/bin/sh
printf '%s\n' 'REA fixture: startup deliberately failed' >&2
exit 42
SH
chmod 700 "$work_dir/fake-browser"
scenario=$(REA_EXE="$work_dir/fake-browser" node -p 'JSON.stringify({browser:{mode:"launch",executable_path:process.env.REA_EXE},start_url:{url:"http://127.0.0.1:1/"},actions:[{step_id:"wait",action:"wait_for_timeout",duration_ms:1}]})')
  1. Run the same request with the executable present and then absent:
for variant in executable absent; do
  if [ "$variant" = absent ]; then
    REA_FIXTURE="$work_dir/fake-browser" node -e 'require("node:fs").unlinkSync(process.env.REA_FIXTURE)'
  fi
  env HOME="$work_dir/home" XDG_CONFIG_HOME="$work_dir/config" \
    XDG_DATA_HOME="$work_dir/data" XDG_CACHE_HOME="$work_dir/cache" \
    XDG_STATE_HOME="$work_dir/state" TMPDIR="$work_dir/tmp" \
    REA_LOG_LEVEL=debug \
    node scripts/rea.mjs capture-browser-scenario "$scenario" --json
  printf 'variant=%s exit=%s\n' "$variant" "$?"
done
REA_FIXTURE="$work_dir" node -e 'require("node:fs").rmSync(process.env.REA_FIXTURE,{recursive:true})'
  1. Compare the returned primary errors. Both exit 1 and omit the executable, its stderr marker, and the missing-file reason. The two-case procedure above reproduced once; separate verification runs reproduced the same omission twice more for an absent executable and once more for an exiting executable: five CLI failures in total, all with the diagnostic loss. No HTTP server is needed because launch never establishes a browser session.

Expected behavior

A launch failure should identify the caller-selected executable and preserve a meaningful startup reason, such as a missing file or the selected program's reported failure. Recovery guidance should address that condition.

The browser-scenario contract explicitly permits schema-valid requests whose executable is unavailable on the host. Repository guidelines require preserving caller-selected paths, local output, and meaningful failure reasons across boundaries. These synthetic fixture values contain no credentials or declared sensitive data.

Impact and scope

P2: the command correctly fails, but discards information needed to diagnose and correct the selected runtime. A missing executable and a program reporting a deliberate startup failure become indistinguishable to the caller. This is a bounded recovery defect; the runs do not establish failure of an installed, working browser or corruption of captured evidence.

The selected file can be checked directly. A direct call to the same installed Playwright dependency preserved the absent path, and a direct persistent-context launch of the inert script retained its path, stderr, and exit code 42. MCP, other operating systems, permissions failures, and real-browser success were not exercised.

REA version

Exact node scripts/rea.mjs --version stdout:

6.8.0

Source baseline: 65f1c447344a423fa2785847dbcea1e9a9e2454a.

Runtime and platform

Node.js v24.22.1; macOS 27.0.1; Darwin arm64; installed locked playwright-core 1.64.1. The CLI used isolated HOME, XDG, and temporary directories.

Target and artifact context

A caller-authored shell executable that writes one synthetic stderr line and exits 42; an absent-file variant of the same selection; one loopback start URL and one timeout action. No real target or browser was needed.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

Both variants in step 2 returned this primary error, also retained under details.cleanup_history.primary_error in the full replies:

{
  "code": "execution_failure",
  "category": "execution_failure",
  "message": "Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",
  "retryable": false,
  "remediation": {
    "action": "Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed."
  },
  "details": {
    "provider_id": "rea-playwright-browser-scenario",
    "operation": "capture_browser_scenario"
  }
}

The full replies additionally carried a sibling cleanup_incomplete diagnostic saying cleanup capabilities remained retained. It contained no executable or startup cause either. That separate cleanup condition is not the finding, and its underlying host cause was not established in this verification.

Debug stderr reported only CLI command failed with command/status metadata. Direct Playwright controls retained executable doesn't exist at <selected path> for the absent file and the script's stderr plus exitCode=42 for the existing fixture. Paths are represented symbolically here to exclude machine-specific scratch locations.

Applicable contract locators at the baseline: docs/browser-scenario-contract.md:3-12,72-76,192-198; AGENTS.md:13,19,33. docs/browser-observation.md:664-666 preserves primary discovery/attachment errors when socket cleanup fails; that rule is about passive CDP attachment and is not cited as a launch-specific schema promise.

Analysis or suspected cause

Source-derived explanation: the CLI enters the production provider through src/cliBrowserScenarioCommands.ts:37-96 and src/composition/browserScenario.ts. The launch boundary passes the selected executable to Playwright, then forwards failures through cleanup in src/browser/PlaywrightScenarioBrowser.ts:654-680,868-915. Raw failures become ProviderAdapterError with a cause, including through src/browser/PlaywrightBrowserScenarioProvider.ts:453-462.

src/domain/analysisErrorProjection.ts:459-469 projects provider identity and cleanup fields without the launch cause. src/domain/analysisErrorPresentation.ts:426-437 supplies the generic doctor advice. This explains why useful information present in Playwright's error disappears from the public response; changing only the top-level message would not restore the missing executable and reason.

Additional context

Related reports were checked and are distinct: #7167 concerns connect-mode capture against an existing browser, #2272 concerns Electron filesystem admission, #4659 concerns temporary artifacts after failed or terminated launches, and #5989 concerns a CDP primary error overwritten by socket cleanup. None has the same closure criterion of an actionable browser-launch diagnostic for the selected executable. No regression from a previously claimed fix is asserted.

Originally created by @coygeek on GitHub (Oct 27, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7554 ### 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 Process capture or runtime observation ### Observed behavior Running `node scripts/rea.mjs capture-browser-scenario "$scenario" --json` with a launch-mode scenario returns the same generic `execution_failure` for two distinct host conditions: the selected executable exits immediately with a diagnostic on stderr, or that executable no longer exists. Neither response identifies the selected executable or explains its startup failure. Both tell the caller to run `rea doctor` and review details that contain no launch diagnosis. This was observed through the built public CLI. Debug logging also omitted the path and startup reason. No real browser or GUI application was launched. ### Reproduction 1. From the built baseline checkout, with Node 24.22.1 on PATH, create an inert executable and a schema-valid scenario: ```sh work_dir=$(mktemp -d) mkdir -p "$work_dir"/{home,config,data,cache,state,tmp} cat > "$work_dir/fake-browser" <<'SH' #!/bin/sh printf '%s\n' 'REA fixture: startup deliberately failed' >&2 exit 42 SH chmod 700 "$work_dir/fake-browser" scenario=$(REA_EXE="$work_dir/fake-browser" node -p 'JSON.stringify({browser:{mode:"launch",executable_path:process.env.REA_EXE},start_url:{url:"http://127.0.0.1:1/"},actions:[{step_id:"wait",action:"wait_for_timeout",duration_ms:1}]})') ``` 2. Run the same request with the executable present and then absent: ```sh for variant in executable absent; do if [ "$variant" = absent ]; then REA_FIXTURE="$work_dir/fake-browser" node -e 'require("node:fs").unlinkSync(process.env.REA_FIXTURE)' fi env HOME="$work_dir/home" XDG_CONFIG_HOME="$work_dir/config" \ XDG_DATA_HOME="$work_dir/data" XDG_CACHE_HOME="$work_dir/cache" \ XDG_STATE_HOME="$work_dir/state" TMPDIR="$work_dir/tmp" \ REA_LOG_LEVEL=debug \ node scripts/rea.mjs capture-browser-scenario "$scenario" --json printf 'variant=%s exit=%s\n' "$variant" "$?" done REA_FIXTURE="$work_dir" node -e 'require("node:fs").rmSync(process.env.REA_FIXTURE,{recursive:true})' ``` 3. Compare the returned primary errors. Both exit 1 and omit the executable, its stderr marker, and the missing-file reason. The two-case procedure above reproduced once; separate verification runs reproduced the same omission twice more for an absent executable and once more for an exiting executable: five CLI failures in total, all with the diagnostic loss. No HTTP server is needed because launch never establishes a browser session. ### Expected behavior A launch failure should identify the caller-selected executable and preserve a meaningful startup reason, such as a missing file or the selected program's reported failure. Recovery guidance should address that condition. The browser-scenario contract explicitly permits schema-valid requests whose executable is unavailable on the host. Repository guidelines require preserving caller-selected paths, local output, and meaningful failure reasons across boundaries. These synthetic fixture values contain no credentials or declared sensitive data. ### Impact and scope P2: the command correctly fails, but discards information needed to diagnose and correct the selected runtime. A missing executable and a program reporting a deliberate startup failure become indistinguishable to the caller. This is a bounded recovery defect; the runs do not establish failure of an installed, working browser or corruption of captured evidence. The selected file can be checked directly. A direct call to the same installed Playwright dependency preserved the absent path, and a direct persistent-context launch of the inert script retained its path, stderr, and exit code 42. MCP, other operating systems, permissions failures, and real-browser success were not exercised. ### REA version Exact `node scripts/rea.mjs --version` stdout: ```text 6.8.0 ``` Source baseline: `65f1c447344a423fa2785847dbcea1e9a9e2454a`. ### Runtime and platform Node.js `v24.22.1`; macOS `27.0.1`; Darwin arm64; installed locked `playwright-core` `1.64.1`. The CLI used isolated HOME, XDG, and temporary directories. ### Target and artifact context A caller-authored shell executable that writes one synthetic stderr line and exits 42; an absent-file variant of the same selection; one loopback start URL and one timeout action. No real target or browser was needed. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence Both variants in step 2 returned this primary error, also retained under `details.cleanup_history.primary_error` in the full replies: ```json { "code": "execution_failure", "category": "execution_failure", "message": "Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.", "retryable": false, "remediation": { "action": "Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed." }, "details": { "provider_id": "rea-playwright-browser-scenario", "operation": "capture_browser_scenario" } } ``` The full replies additionally carried a sibling `cleanup_incomplete` diagnostic saying cleanup capabilities remained retained. It contained no executable or startup cause either. That separate cleanup condition is not the finding, and its underlying host cause was not established in this verification. Debug stderr reported only `CLI command failed` with command/status metadata. Direct Playwright controls retained `executable doesn't exist at <selected path>` for the absent file and the script's stderr plus `exitCode=42` for the existing fixture. Paths are represented symbolically here to exclude machine-specific scratch locations. Applicable contract locators at the baseline: `docs/browser-scenario-contract.md:3-12,72-76,192-198`; `AGENTS.md:13,19,33`. `docs/browser-observation.md:664-666` preserves primary discovery/attachment errors when socket cleanup fails; that rule is about passive CDP attachment and is not cited as a launch-specific schema promise. ### Analysis or suspected cause Source-derived explanation: the CLI enters the production provider through `src/cliBrowserScenarioCommands.ts:37-96` and `src/composition/browserScenario.ts`. The launch boundary passes the selected executable to Playwright, then forwards failures through cleanup in `src/browser/PlaywrightScenarioBrowser.ts:654-680,868-915`. Raw failures become `ProviderAdapterError` with a cause, including through `src/browser/PlaywrightBrowserScenarioProvider.ts:453-462`. `src/domain/analysisErrorProjection.ts:459-469` projects provider identity and cleanup fields without the launch cause. `src/domain/analysisErrorPresentation.ts:426-437` supplies the generic doctor advice. This explains why useful information present in Playwright's error disappears from the public response; changing only the top-level message would not restore the missing executable and reason. ### Additional context Related reports were checked and are distinct: #7167 concerns connect-mode capture against an existing browser, #2272 concerns Electron filesystem admission, #4659 concerns temporary artifacts after failed or terminated launches, and #5989 concerns a CDP primary error overwritten by socket cleanup. None has the same closure criterion of an actionable browser-launch diagnostic for the selected executable. No regression from a previously claimed fix is asserted.
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#4492
No description provided.