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

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f3e12bd-3682-4a6c-8891-2516411bd70e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ 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
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.

1 participant