[GH-ISSUE #5393] [Bug] JavaScript analysis worker replaces an observed failing exit with later cancellation #3264

Closed
opened 2026-10-31 00:38:32 +00:00 by bsakaguchi · 3 comments
Owner

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

Before submitting

  • I searched open and closed issues and related PRs. #5292 covers the shared OwnedCommand owner; this worker uses its own supervisor path. #5388 is the source-map owner, and #4227 tracks the broader lifecycle audit.
  • This report contains no credentials, private target samples, or sensitive values.

Area

Evidence, artifacts, or reconstruction

Observed behavior

A controlled source-boundary test of JavaScriptAnalysisWorker.analyze returns AnalysisCancelledError when the caller aborts after the owned child has exited with code 7. The otherwise identical no-abort control returns ProviderAdapterError with diagnostics.exit_code: 7.

Reproduction

Executed on source 799e8265b254e225dc1dabdd25e56f0ab7f86bd3 with Node 24.18.0 on macOS 26.3 arm64:

  1. Construct the production JavaScriptAnalysisWorker with limits {heapMb:128, timeoutMs:30000} and its existing launcher seam.
  2. Launch an owned Node peer through spawnOwnedProviderProcess. The peer emits a valid ready frame using its real V8 heap limit, then exits 7 after receiving the analysis request. It emits no analysis result and executes no supplied JavaScript artifact.
  3. Schedule controller.abort(opaqueReason) with setImmediate from the child's exit listener. The supervisor's synchronous exit listener runs before the queued abort (source-confirmed event ordering).
  4. Call worker.analyze with a small inert JavaScript file record and the signal. Close the worker in finally.

The no-abort expectation passed. The post-exit abort expectation failed: expected ProviderAdapterError/exit 7, received AnalysisCancelledError. The exact probe source and red log are retained in the local audit record; the test observed the child exit event and source-confirmed listener ordering, rather than directly inspecting the private supervisor snapshot.

Expected behavior

Preserve a previously observed physical worker failure as primary when interruption arrives later. Caller cancellation observed first must remain cancellation. Preserve available checkpoints, resource-limit classification, and retained cleanup ownership/retry semantics.

Impact and scope

The observed error classification hides the earlier worker failure. Runtime frequency is NOT_ENOUGH_INFO. This was an authored Node peer at the production worker boundary, not a complete semantic-analysis workload or a public CLI/MCP reproduction. Cleanup refusal/retry under this exact ordering was not injected.

REA version

Executed at source 799e8265b254e225dc1dabdd25e56f0ab7f86bd3 (package 6.7.0). Live main 074768901f3cdc8205b61773fb1faf6f6c7b3ca8 still has the relevant interruption-first branches; that revision was source-inspected, not executed.

Runtime and platform

Node.js 24.18.0; macOS 26.3 arm64.

Target and artifact context

Inert local JavaScript source record; real owned Node protocol peer; no target execution or debugger.

Interface

Other: direct production worker boundary.

Earliest failure stage

Cleanup, cancellation, or lifecycle.

Relevant output or evidence

No-abort control: ProviderAdapterError, diagnostics.exit_code = 7
Abort queued after child exit: AnalysisCancelledError

Source-derived cause: #next checks ambient interruption before the supervisor snapshot; #failure also selects cancellation ahead of physical error interpretation. This direct owner does not use runOwnedCommand, so its #5292 correction does not cover this branch.

Typed outcome or recovery expected

The observed exit-7 adapter error, retaining captured diagnostics and partial facts. A cleanup refusal must still retain its exact owner/resources and remain retryable.

Additional context

This finding came from checking nearby consumers of the confirmed first-failure ordering defect. No fix is integrated yet. No claim of real OS memory-limit behavior, public client delivery, performance improvement, or customer reproduction is made.

Originally created by @morluto on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5393 ### Before submitting - [x] I searched open and closed issues and related PRs. #5292 covers the shared `OwnedCommand` owner; this worker uses its own supervisor path. #5388 is the source-map owner, and #4227 tracks the broader lifecycle audit. - [x] This report contains no credentials, private target samples, or sensitive values. ### Area Evidence, artifacts, or reconstruction ### Observed behavior A controlled source-boundary test of `JavaScriptAnalysisWorker.analyze` returns `AnalysisCancelledError` when the caller aborts after the owned child has exited with code 7. The otherwise identical no-abort control returns `ProviderAdapterError` with `diagnostics.exit_code: 7`. ### Reproduction Executed on source `799e8265b254e225dc1dabdd25e56f0ab7f86bd3` with Node 24.18.0 on macOS 26.3 arm64: 1. Construct the production `JavaScriptAnalysisWorker` with limits `{heapMb:128, timeoutMs:30000}` and its existing launcher seam. 2. Launch an owned Node peer through `spawnOwnedProviderProcess`. The peer emits a valid `ready` frame using its real V8 heap limit, then exits 7 after receiving the analysis request. It emits no analysis result and executes no supplied JavaScript artifact. 3. Schedule `controller.abort(opaqueReason)` with `setImmediate` from the child's `exit` listener. The supervisor's synchronous exit listener runs before the queued abort (source-confirmed event ordering). 4. Call `worker.analyze` with a small inert JavaScript file record and the signal. Close the worker in `finally`. The no-abort expectation passed. The post-exit abort expectation failed: expected `ProviderAdapterError`/exit 7, received `AnalysisCancelledError`. The exact probe source and red log are retained in the local audit record; the test observed the child exit event and source-confirmed listener ordering, rather than directly inspecting the private supervisor snapshot. ### Expected behavior Preserve a previously observed physical worker failure as primary when interruption arrives later. Caller cancellation observed first must remain cancellation. Preserve available checkpoints, resource-limit classification, and retained cleanup ownership/retry semantics. ### Impact and scope The observed error classification hides the earlier worker failure. Runtime frequency is NOT_ENOUGH_INFO. This was an authored Node peer at the production worker boundary, not a complete semantic-analysis workload or a public CLI/MCP reproduction. Cleanup refusal/retry under this exact ordering was not injected. ### REA version Executed at source `799e8265b254e225dc1dabdd25e56f0ab7f86bd3` (package 6.7.0). Live main `074768901f3cdc8205b61773fb1faf6f6c7b3ca8` still has the relevant interruption-first branches; that revision was source-inspected, not executed. ### Runtime and platform Node.js 24.18.0; macOS 26.3 arm64. ### Target and artifact context Inert local JavaScript source record; real owned Node protocol peer; no target execution or debugger. ### Interface Other: direct production worker boundary. ### Earliest failure stage Cleanup, cancellation, or lifecycle. ### Relevant output or evidence ```text No-abort control: ProviderAdapterError, diagnostics.exit_code = 7 Abort queued after child exit: AnalysisCancelledError ``` Source-derived cause: [`#next`](https://github.com/morluto/rea/blob/799e8265b254e225dc1dabdd25e56f0ab7f86bd3/src/javascript/analysis/JavaScriptAnalysisWorker.ts#L511) checks ambient interruption before the supervisor snapshot; [`#failure`](https://github.com/morluto/rea/blob/799e8265b254e225dc1dabdd25e56f0ab7f86bd3/src/javascript/analysis/JavaScriptAnalysisWorker.ts#L705) also selects cancellation ahead of physical error interpretation. This direct owner does not use `runOwnedCommand`, so its #5292 correction does not cover this branch. ### Typed outcome or recovery expected The observed exit-7 adapter error, retaining captured diagnostics and partial facts. A cleanup refusal must still retain its exact owner/resources and remain retryable. ### Additional context This finding came from checking nearby consumers of the confirmed first-failure ordering defect. No fix is integrated yet. No claim of real OS memory-limit behavior, public client delivery, performance improvement, or customer reproduction is made.
bsakaguchi 2026-10-31 00:38:32 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

@ShuaixinHuang commented on GitHub (Oct 20, 2026):

@morluto, a brief review-routing request: could you please respond in #5347 about #4941, #4946 and #4947? Their latest verified CI results and validation limits are recorded there.

I have further independent fixes ready, but all three open-PR slots are occupied. A reviewer assignment, a rough review/merge window, or clear guidance on how to free a slot would help me continue contributing.

Please reply in #5347 so this bug discussion can stay focused. Thank you.

<!-- gh-comment-id:6287728603 --> @ShuaixinHuang commented on GitHub (Oct 20, 2026): @morluto, a brief review-routing request: could you please respond in #5347 about #4941, #4946 and #4947? Their latest verified CI results and validation limits are recorded there. I have further independent fixes ready, but all three open-PR slots are occupied. A reviewer assignment, a rough review/merge window, or clear guidance on how to free a slot would help me continue contributing. Please reply in #5347 so this bug discussion can stay focused. Thank you.
Author
Owner

@Abdulrahman3M commented on GitHub (Oct 20, 2026):

Hi @morluto — I found that #5393 shares the same first-observed-failure / later-cancellation ordering problem as #5419, but in the separate JavaScriptAnalysisWorker owner.

I prepared a separate candidate patch for this issue, rather than claiming the WebBundle patch also fixes this worker:

Branch: https://github.com/Abdulrahman3M/REA/tree/fix/javascript-worker-observed-exit-5393

The change records a nonzero/signal worker exit at the supervisor's synchronous diagnostic boundary before a later abort can override its classification. It then preserves the worker's primary ProviderAdapterError (or memory classification) with exit status and bounded stderr, while retaining a later opaque abort reason as a secondary failure. It also retains the exact abort reason when cancellation is genuinely first.

I added real-owned-Node-child controls for exit code 7 with and without a later queueMicrotask abort.

Verification limits: This is an unverified candidate, not an established fix. I have inspected the code and committed regression tests, but have not run these tests or project checks or reproduced your macOS/Node 24.18.0 setup. No PR is open.

If you have an opportunity, could you try this branch with the original #5393 reproduction and share whether it now retains ProviderAdapterError, diagnostics.exit_code = 7, and stderr after post-exit abort, while preserving cancellation when the abort is first? Please report any errors, including differences in checkpoint/cleanup behavior.

Suggested checks:

npm ci
npm run test:focused -- tests/boundary/javascript/javascriptSourceAnalysisWorker.test.ts
npm run check:fast

Once the regression and checks are verified, I can refine the patch and prepare a focused PR. Thanks!

<!-- gh-comment-id:6289162510 --> @Abdulrahman3M commented on GitHub (Oct 20, 2026): Hi @morluto — I found that #5393 shares the same first-observed-failure / later-cancellation ordering problem as #5419, but in the separate `JavaScriptAnalysisWorker` owner. I prepared a **separate candidate patch** for this issue, rather than claiming the WebBundle patch also fixes this worker: **Branch:** https://github.com/Abdulrahman3M/REA/tree/fix/javascript-worker-observed-exit-5393 The change records a nonzero/signal worker exit at the supervisor's synchronous diagnostic boundary before a later abort can override its classification. It then preserves the worker's primary `ProviderAdapterError` (or memory classification) with exit status and bounded stderr, while retaining a later opaque abort reason as a secondary failure. It also retains the exact abort reason when cancellation is genuinely first. I added real-owned-Node-child controls for exit code 7 with and without a later `queueMicrotask` abort. **Verification limits:** This is an *unverified candidate*, not an established fix. I have inspected the code and committed regression tests, but have **not run these tests or project checks** or reproduced your macOS/Node 24.18.0 setup. No PR is open. If you have an opportunity, could you try this branch with the original #5393 reproduction and share whether it now retains `ProviderAdapterError`, `diagnostics.exit_code = 7`, and stderr after post-exit abort, while preserving cancellation when the abort is first? Please report any errors, including differences in checkpoint/cleanup behavior. Suggested checks: ```bash npm ci npm run test:focused -- tests/boundary/javascript/javascriptSourceAnalysisWorker.test.ts npm run check:fast ``` Once the regression and checks are verified, I can refine the patch and prepare a focused PR. Thanks!
Author
Owner

@morluto commented on GitHub (Oct 21, 2026):

Closing as already fixed on main.

Verified on 71b696582 with npm run test:focused -- tests/boundary/javascript/workerOrderAudit.test.ts (35 passed): an owned Node peer that exits 7, then aborts, stays ProviderAdapterError with diagnostics.exit_code: 7; the abort reason is a secondary AnalysisCancelledError. Fix commit f01dccab7.

<!-- gh-comment-id:6308572138 --> @morluto commented on GitHub (Oct 21, 2026): Closing as already fixed on main. Verified on `71b696582` with `npm run test:focused -- tests/boundary/javascript/workerOrderAudit.test.ts` (35 passed): an owned Node peer that exits 7, then aborts, stays `ProviderAdapterError` with `diagnostics.exit_code: 7`; the abort reason is a secondary `AnalysisCancelledError`. Fix commit `f01dccab7`.
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#3264
No description provided.