[GH-ISSUE #5059] [Bug] Secondary lifecycle failure retention replaces the primary error cause #3103

Closed
opened 2026-10-31 00:36:41 +00:00 by bsakaguchi · 1 comment
Owner

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

Observed behavior

AnalysisError.retainSecondaryFailure replaces the primary error's direct cause with an AggregateError when a later lifecycle failure is retained. The typed primary and original cause remain nested but the exact producer/caller cause contract is broken.

Executed evidence

On unchanged main 36d156ff05f48f9f0b4c4abb8f7c899249a49ebf, strengthened the existing production MCP Rizin-handler retirement-failure test. The operation returns an AnalysisInputError with an exact reason object, then session retirement reports a separate error. The direct primary cause is now an AggregateError rather than the original reason; the exact-cause assertion fails (one selected failure, 12 skipped). This is a controlled production handler/admission test, not a live debugger run or full model/stdio workflow.

The same shared method is used by LLDB partial/descriptor cleanup and ADB input staging and by the shared MCP external-mutation admission helper. For AnalysisCancelledError, caller reason identity must likewise remain exact; this broader scope is source-derived until the regression checks run.

Root cause and expected design

The error owner represents secondary lifecycle facts by rewriting the causal origin. Retain exact typed secondary failures separately at that owner, preserving original direct cause, typed identity, partial observations and live cleanup ownership. Existing caller-safe diagnostic projections should still expose the secondary outcome. Consumers should read the separate owned fact instead of parsing an AggregateError shape to recover the primary reason. Related LLDB available-prefix issue #5058 exposed this structural problem during fix review.

Scope and limitations

Existing error composition only; no execution authority or protocol additions. Searched open/closed secondary/cause reports; #4375 concerns diagnostic key merging and#4240 cleanup-resource composition rather than exact cause preservation. Full live ADB/LLDB/debugger behavior, platform lanes and whole-agent costs: NOT_ENOUGH_INFO. No performance claim.

Originally created by @morluto on GitHub (Oct 18, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5059 ### Observed behavior `AnalysisError.retainSecondaryFailure` replaces the primary error's direct `cause` with an AggregateError when a later lifecycle failure is retained. The typed primary and original cause remain nested but the exact producer/caller cause contract is broken. ### Executed evidence On unchanged main `36d156ff05f48f9f0b4c4abb8f7c899249a49ebf`, strengthened the existing production MCP Rizin-handler retirement-failure test. The operation returns an AnalysisInputError with an exact reason object, then session retirement reports a separate error. The direct primary cause is now an AggregateError rather than the original reason; the exact-cause assertion fails (one selected failure, 12 skipped). This is a controlled production handler/admission test, not a live debugger run or full model/stdio workflow. The same shared method is used by LLDB partial/descriptor cleanup and ADB input staging and by the shared MCP external-mutation admission helper. For AnalysisCancelledError, caller reason identity must likewise remain exact; this broader scope is source-derived until the regression checks run. ### Root cause and expected design The error owner represents secondary lifecycle facts by rewriting the causal origin. Retain exact typed secondary failures separately at that owner, preserving original direct cause, typed identity, partial observations and live cleanup ownership. Existing caller-safe diagnostic projections should still expose the secondary outcome. Consumers should read the separate owned fact instead of parsing an AggregateError shape to recover the primary reason. Related LLDB available-prefix issue #5058 exposed this structural problem during fix review. ### Scope and limitations Existing error composition only; no execution authority or protocol additions. Searched open/closed secondary/cause reports; #4375 concerns diagnostic key merging and#4240 cleanup-resource composition rather than exact cause preservation. Full live ADB/LLDB/debugger behavior, platform lanes and whole-agent costs: NOT_ENOUGH_INFO. No performance claim.
Author
Owner

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

Fixed on main in d4e233946. Root cause: the shared error owner encoded later lifecycle failures by replacing the original direct cause. It now keeps exact typed secondary failures separately in secondaryFailures, while retaining original direct cause (including undefined), typed identity, diagnostics, output and live cleanup ownership. The affected ADB and MCP regression checks inspect the owned secondary fact instead of parsing an aggregate cause.

Unchanged-main MCP-handler regression failed exact-cause identity. Domain controls now verify caller reason identity and absent-cause semantics; ADB snapshot ownership and MCP retirement tests preserve their secondary facts. The LLDB cancellation-plus-prefix EIO/failed-close regression also retains exact caller reason through recovery.

Validation: final affected selection passed 162 tests in 13 files; one existing 8 MiB journal allocation test skipped. Full npm run check, independent Luna reviews and commit hooks passed. Controlled production readback/provider/MCP and error-owner workflows; no actual LLDB, ADB device, GUI or storage fault. Bounded completed LLDB trace/close warm medians (two repeats/build plus separate first processes): baseline → candidate elapsed 0.16447 → 0.16405 s, CPU 0.25947 → 0.25865 s, sampled family RSS 193.8 → 194.2 MB, reply estimate 307 → 307 cl100k tokens. No true cold-cache, whole-agent or injected-failure cost measurement; no performance claim. Exact replies and probe records retained locally.

No directly related downstream cause-repair workaround remains. This restores the shared cause contract rather than adding interpretation in callers.

<!-- gh-comment-id:6253312945 --> @morluto commented on GitHub (Oct 18, 2026): Fixed on main in d4e233946. Root cause: the shared error owner encoded later lifecycle failures by replacing the original direct cause. It now keeps exact typed secondary failures separately in `secondaryFailures`, while retaining original direct cause (including undefined), typed identity, diagnostics, output and live cleanup ownership. The affected ADB and MCP regression checks inspect the owned secondary fact instead of parsing an aggregate cause. Unchanged-main MCP-handler regression failed exact-cause identity. Domain controls now verify caller reason identity and absent-cause semantics; ADB snapshot ownership and MCP retirement tests preserve their secondary facts. The LLDB cancellation-plus-prefix EIO/failed-close regression also retains exact caller reason through recovery. Validation: final affected selection passed 162 tests in 13 files; one existing 8 MiB journal allocation test skipped. Full `npm run check`, independent Luna reviews and commit hooks passed. Controlled production readback/provider/MCP and error-owner workflows; no actual LLDB, ADB device, GUI or storage fault. Bounded completed LLDB trace/close warm medians (two repeats/build plus separate first processes): baseline → candidate elapsed 0.16447 → 0.16405 s, CPU 0.25947 → 0.25865 s, sampled family RSS 193.8 → 194.2 MB, reply estimate 307 → 307 cl100k tokens. No true cold-cache, whole-agent or injected-failure cost measurement; no performance claim. Exact replies and probe records retained locally. No directly related downstream cause-repair workaround remains. This restores the shared cause contract rather than adding interpretation in callers.
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#3103
No description provided.