[GH-ISSUE #4444] [Bug] build_reconstruction_obligation_ledger reports a missing review record or duplicate record IDs as unreadable_output ("run rea doctor") #1762

Closed
opened 2026-10-16 21:09:59 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

  • I searched the open and closed issues for a related report (obligation ledger, unreadable_output, "Reviewed obligation Evidence is missing"). Sibling of #3219, which was fixed by 3a34ad37b for non-canonical bundles only. Open PR #3288 adds a test for that same non-canonical case and doesn't change the error mapping.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

Two caller-input mistakes make build-reconstruction-obligation-ledger / build_reconstruction_obligation_ledger fail as an internal error:

{"error":"Application workflow failed","code":"unreadable_output","category":"execution_failure",
 "message":"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",
 "retryable":false}

There are no details, so the caller can't tell which input is wrong.

  1. A review_evidence_ids entry that isn't in evidence_bundle.records. This is the case a user hits by following docs/reconstruction-obligation-ledgers.md literally: paste one of the "Reviewed obligation examples" (sample ID ev_aaaa…) into the "Complete CLI request" from the same page.
  2. An Evidence bundle that contains the same record twice.

evaluate_reconstruction_coverage returns invalid_request / invalid_input for the equivalent inputs, with the reason in details.issues:

{"code":"invalid_request","category":"invalid_input",
 "details":{"issues":[{"path":[],"reason":"invalid_value","message":"Evidence bundle contains duplicate record IDs"}]}}

and Coverage workspace Evidence is missing: ev_… for a missing cited record.

Cause (source-derived on main @ d72d856f5): deriveReconstructionObligationCandidates throws TypeError("Reviewed obligation Evidence is missing: <id>") (src/application/ReconstructionObligationCandidates.ts:326), and bundle parsing throws TypeError("Evidence bundle contains duplicate record IDs") (src/domain/evidenceBundle.ts). buildReconstructionObligationLedgerEvidenceValidated (src/application/ReconstructionObligationLedgerService.ts) maps only NonCanonicalEvidenceBundleError and z.ZodError to workflowInputError. Every other TypeError becomes AnalysisProtocolError, which is presented as unreadable_output. ReconstructionCoverageService.ts maps cause instanceof TypeError || cause instanceof z.ZodError to workflowInputError. Other caller-reachable TypeErrors in the same path, such as the residual-unknown graph checks in evidenceBundle.ts, would presumably be affected the same way (not tested).

Reproduction

Minimal request: an empty bundle plus one reviewed obligation whose review_evidence_ids is ["ev_" + "a"×64]. The other fields are the docs' example fields with required_case_kinds: ["positive"].

rea build-reconstruction-obligation-ledger /tmp/min12.json --json

Same result on rea-agents@6.5.0, the main @ d72d856f5 CLI and the main stdio MCP tool. For case 2, append a copy of evidence_bundle.records[0] to an otherwise valid request.

Expected behavior

invalid_request / invalid_input with the TypeError message as an issue, as evaluate_reconstruction_coverage already does. That means mapping caller-input TypeErrors in the ledger service the same way, or throwing typed input errors at those two sites.

Impact and scope

  • Anyone trying the documented example, and anyone whose bundle and reviewed obligations drift apart. The message sends them to rea doctor, which doesn't help.
  • Tested: the two cases above on 6.5.0 and main. Everything else I tried in the ledger was classified as documented: verifier fail → failed, a contradiction → contradicted, a duplicate binding → unowned, a missing dependency → blocked, out-of-scope kept as a disposition, and static or inferred Evidence flagged as weak-*-authority so process and runtime claims stay open.
Originally created by @Rinkia on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4444 ### Before submitting - [x] I searched the open and closed issues for a related report (obligation ledger, unreadable_output, "Reviewed obligation Evidence is missing"). Sibling of #3219, which was fixed by 3a34ad37b for non-canonical bundles only. Open PR #3288 adds a test for that same non-canonical case and doesn't change the error mapping. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior Two caller-input mistakes make `build-reconstruction-obligation-ledger` / `build_reconstruction_obligation_ledger` fail as an internal error: ```json {"error":"Application workflow failed","code":"unreadable_output","category":"execution_failure", "message":"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.", "retryable":false} ``` There are no `details`, so the caller can't tell which input is wrong. 1. **A `review_evidence_ids` entry that isn't in `evidence_bundle.records`.** This is the case a user hits by following `docs/reconstruction-obligation-ledgers.md` literally: paste one of the "Reviewed obligation examples" (sample ID `ev_aaaa…`) into the "Complete CLI request" from the same page. 2. **An Evidence bundle that contains the same record twice.** `evaluate_reconstruction_coverage` returns `invalid_request` / `invalid_input` for the equivalent inputs, with the reason in `details.issues`: ```json {"code":"invalid_request","category":"invalid_input", "details":{"issues":[{"path":[],"reason":"invalid_value","message":"Evidence bundle contains duplicate record IDs"}]}} ``` and `Coverage workspace Evidence is missing: ev_…` for a missing cited record. **Cause** (source-derived on `main` @ `d72d856f5`): `deriveReconstructionObligationCandidates` throws `TypeError("Reviewed obligation Evidence is missing: <id>")` (`src/application/ReconstructionObligationCandidates.ts:326`), and bundle parsing throws `TypeError("Evidence bundle contains duplicate record IDs")` (`src/domain/evidenceBundle.ts`). `buildReconstructionObligationLedgerEvidenceValidated` (`src/application/ReconstructionObligationLedgerService.ts`) maps only `NonCanonicalEvidenceBundleError` and `z.ZodError` to `workflowInputError`. Every other `TypeError` becomes `AnalysisProtocolError`, which is presented as `unreadable_output`. `ReconstructionCoverageService.ts` maps `cause instanceof TypeError || cause instanceof z.ZodError` to `workflowInputError`. Other caller-reachable `TypeError`s in the same path, such as the residual-unknown graph checks in `evidenceBundle.ts`, would presumably be affected the same way (not tested). ### Reproduction Minimal request: an empty bundle plus one reviewed obligation whose `review_evidence_ids` is `["ev_" + "a"×64]`. The other fields are the docs' example fields with `required_case_kinds: ["positive"]`. ```sh rea build-reconstruction-obligation-ledger /tmp/min12.json --json ``` Same result on `rea-agents@6.5.0`, the `main` @ `d72d856f5` CLI and the `main` stdio MCP tool. For case 2, append a copy of `evidence_bundle.records[0]` to an otherwise valid request. ### Expected behavior `invalid_request` / `invalid_input` with the `TypeError` message as an issue, as `evaluate_reconstruction_coverage` already does. That means mapping caller-input `TypeError`s in the ledger service the same way, or throwing typed input errors at those two sites. ### Impact and scope - Anyone trying the documented example, and anyone whose bundle and reviewed obligations drift apart. The message sends them to `rea doctor`, which doesn't help. - Tested: the two cases above on 6.5.0 and main. Everything else I tried in the ledger was classified as documented: verifier `fail` → `failed`, a contradiction → `contradicted`, a duplicate binding → `unowned`, a missing dependency → `blocked`, `out-of-scope` kept as a disposition, and static or inferred Evidence flagged as `weak-*-authority` so process and runtime claims stay open.
Author
Owner

@amyanger commented on GitHub (Oct 16, 2026):

I'd like to tackle this one if it is okay!

<!-- gh-comment-id:6214503209 --> @amyanger commented on GitHub (Oct 16, 2026): I'd like to tackle this one if it is okay!
Author
Owner

@matbrgz commented on GitHub (Oct 16, 2026):

Cross-referencing with sibling obligation ledger report #3370 ([Bug] Reconstruction obligation ledgers lose semantic unknowns and report complete coverage). Both issues isolate validation and outcome projection defects in build_reconstruction_obligation_ledger.

Consolidated under Cluster V (Reconstruction Obligation Ledgers & Ledger Integrity) in tracker #4330.

<!-- gh-comment-id:6219890390 --> @matbrgz commented on GitHub (Oct 16, 2026): Cross-referencing with sibling obligation ledger report #3370 (`[Bug] Reconstruction obligation ledgers lose semantic unknowns and report complete coverage`). Both issues isolate validation and outcome projection defects in `build_reconstruction_obligation_ledger`. Consolidated under **Cluster V (Reconstruction Obligation Ledgers & Ledger Integrity)** in tracker #4330.
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#1762
No description provided.