Skip to content

fix(jsonl): map lifecycle guard errors to invalid_request#449

Open
dalledajay-coder wants to merge 1 commit into
vouchdev:testfrom
dalledajay-coder:fix/jsonl-lifecycle-error-mapping
Open

fix(jsonl): map lifecycle guard errors to invalid_request#449
dalledajay-coder wants to merge 1 commit into
vouchdev:testfrom
dalledajay-coder:fix/jsonl-lifecycle-error-mapping

Conversation

@dalledajay-coder

Copy link
Copy Markdown

What changed

handle_request in the JSONL server now includes LifecycleError in the caller-visible domain-error tuple, next to ProposalError, so lifecycle guard failures map to {"code": "invalid_request"} instead of falling through to the generic internal_error branch. one import, one tuple entry, a regression test, and a changelog line.

Why

the envelope treated ValueError / ProposalError / ArtifactNotFoundError as bad requests, but LifecycleError — a RuntimeError subclass exactly like ProposalError — fell through to the catch-all. on current test:

{"id": "r1", "method": "kb.supersede", "params": {"old_claim_id": "c1", "new_claim_id": "c1"}}
→ {"id": "r1", "ok": false, "error": {"code": "internal_error", "message": "a claim cannot supersede itself"}}

plus _log.exception dumping a full server-side traceback for what is a caller mistake. the http /rpc transport routes through the same handle_request, so both wire surfaces misreported it — while the cli already translated the identical error into a clean one-liner via _cli_errors (which lists LifecycleError explicitly for this exact reason). an agent retrying on internal_error (a server fault, plausibly transient) will loop on a request that can never succeed; invalid_request tells it the request itself is wrong.

any future lifecycle guard raising LifecycleError gets the correct mapping for free.

Testing

  • tests/test_jsonl_server.py::test_jsonl_lifecycle_guard_maps_to_invalid_request — fails on current test (envelope carries internal_error), passes with the fix; also asserts the guard fired before any write, leaving the claim untouched.

ran locally:

python -m ruff check src tests   # all checks passed
python -m mypy src               # success: no issues found in 91 source files
python -m pytest tests/ -q --ignore=tests/embeddings   # 1151 passed, 28 skipped

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@plind-junior, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 57 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 555236c1-6915-4e04-bfed-1002b49b56f9

📥 Commits

Reviewing files that changed from the base of the PR and between b0674f1 and 66ad6e8.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • src/vouch/jsonl_server.py
  • tests/test_jsonl_server.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added docs documentation, specs, examples, and repo guidance mcp mcp, jsonl, and http surfaces tests tests and fixtures size: XS less than 50 changed non-doc lines labels Jul 9, 2026
handle_request caught ValueError, ProposalError and ArtifactNotFoundError
as caller-visible conditions, but LifecycleError (a RuntimeError subclass
like ProposalError) fell through to the generic branch: kb.supersede of a
claim onto itself came back as internal_error and logged a full
server-side traceback for what is a bad request. the http /rpc transport
shares the same envelope, so both wire surfaces misreported it while the
cli already mapped the identical error to a clean one-liner via
_cli_errors.

add LifecycleError to the domain-error tuple so lifecycle guards surface
as invalid_request on every transport, and cover it with a regression
test that fails on the previous code.
@dalledajay-coder
dalledajay-coder force-pushed the fix/jsonl-lifecycle-error-mapping branch from 2ca2f62 to 66ad6e8 Compare July 10, 2026 10:36
@plind-junior

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs documentation, specs, examples, and repo guidance mcp mcp, jsonl, and http surfaces size: XS less than 50 changed non-doc lines tests tests and fixtures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants