Skip to content

fix(api): return the REQ-010 error envelope on every error path (DEBT-033)#112

Merged
fvadicamo merged 4 commits into
developfrom
fix/debt-033-error-envelope
Jul 15, 2026
Merged

fix(api): return the REQ-010 error envelope on every error path (DEBT-033)#112
fvadicamo merged 4 commits into
developfrom
fix/debt-033-error-envelope

Conversation

@fvadicamo

Copy link
Copy Markdown
Contributor

Summary

DEBT-033: the REQ-010 error envelope ({"error": {category, code, message, remediation, request_id}}) was documented as universal but wasn't. Endpoints that raised HTTPException(status_code=..., detail="some string") returned FastAPI's bare {"detail": "..."} — no code to branch on, no remediation, no request id. This makes the envelope actually universal.

What changed

The DOCS-009 caveat named four bare-shape endpoints (reindex ×2, core conversations, admin conversation turns). Grepping the handlers found the caveat had undercounted — the same bare shape lived on four more paths, so removing the caveat as written would have re-asserted a universality those still broke:

  • POST /api/v1/query — registry-not-initialized (500), query-pipeline-not-configured (503)
  • the admin authentication dependency and the API-key creation path — registry (500), key-store-not-configured (500)
  • GET /api/v1/admin/health?detail=full — service-initializing (503, ×2)

All of them (the four scoped + the four found) now raise ErrorResponse.to_envelope() at the same HTTP status they returned before — the change is shape-only. No test asserted the bare shape, so none needed rewriting; existing status-code assertions still hold.

Error codes

Code Status Where
ERR-CONFIG-001 (reused) 500 provider registry not initialized
ERR-CONFIG-002 (reused) 500 key store not configured
ERR-CONV-001 (new) 404 conversation not found (core + admin)
ERR-CONV-002 (new) 503 conversation store not available
ERR-CONV-003 (new) 501 store cannot decrypt turns (in-memory)
ERR-QUERY-005 (new) 503 query pipeline not available
ERR-ADMIN-008 (new) 503 deep-health auth not ready
ERR-INDEX-003 (new) 400 reindex target equals active version
ERR-INDEX-004 (new) 404 reindex job not found

Reused codes match the global unhandled-exception handler's treatment of internal faults. New codes are registered in vektra_shared/errors.py, _CODE_STATUS_OVERRIDE, and docs/reference/error-codes.md. The "not every endpoint uses the envelope" caveat is removed from docs/reference/api.md.

Follow-up spawned (DEBT-034)

The wire shape is {"detail": {"error": {...}}} for every HTTPException-based error — FastAPI wraps the detail, so the envelope sits one level down for every enveloped endpoint (auth included), while the top-level {"error": {...}} only comes from the global 500 handler. The whole test suite already asserts ["detail"]["error"]["code"], so this is the de-facto contract. api.md shows the logical top-level form; reconciling that representation predates this work and affects every endpoint, so it's filed as DEBT-034 rather than expanded into here.

Verification

  • make lint: ruff + ruff format --check + mypy (76 files) + import-linter (8 contracts) — clean
  • make test: 781 passed, 3 skipped, 52 deselected (integration)
  • New/strengthened tests: test_errors.py (codes, overrides, factories), test_reindex.py (envelope on 400/404), and envelope-code assertions added to the existing conversation and admin-turns tests
  • HTTP-level tests exercise the real FastAPI app, confirming the {"detail":{"error":{code}}} shape end-to-end

No CI workflows were touched; the CI gate and Integration tests + NFR gates checks are unchanged.

🤖 Generated with Claude Code

fvadicamo and others added 2 commits July 15, 2026 08:00
…-033)

Endpoints that raised HTTPException with a plain string detail returned
FastAPI's bare {"detail": "..."} - no code, no remediation, no request
id, so a client could not branch on an error code. The DOCS-009 caveat
named four such endpoints; a grep of the handlers found four more
(POST /query, the admin auth dependency, api-key creation, and admin
/health?detail=full), so removing the caveat as written would have
re-asserted a universality those still broke.

All of them now raise ErrorResponse.to_envelope() at the same HTTP status
they returned before (shape-only; no test asserted the bare shape).
Reused ERR-CONFIG-001/002 for internal registry/key-store faults; added
ERR-CONV-001/002/003, ERR-QUERY-005, ERR-ADMIN-008 and ERR-INDEX-003/004,
each registered in errors.py, _CODE_STATUS_OVERRIDE and error-codes.md.
Removed the "not every endpoint uses the envelope" caveat from api.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fvadicamo fvadicamo added bug Something isn't working documentation Improvements or additions to documentation component:shared vektra-shared component component:core vektra-core component component:index vektra-index component component:admin vektra-admin component labels Jul 15, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 30 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

Run ID: d5b88d0b-3d0a-4e5c-b249-439483ee20a8

📥 Commits

Reviewing files that changed from the base of the PR and between ce7496b and 35b521c.

⛔ Files ignored due to path filters (1)
  • .s2s/BACKLOG.md is excluded by !.s2s/**
📒 Files selected for processing (11)
  • CHANGELOG.md
  • docs/reference/api.md
  • docs/reference/error-codes.md
  • vektra-admin/src/vektra_admin/api.py
  • vektra-admin/tests/test_admin_turns.py
  • vektra-core/src/vektra_core/api.py
  • vektra-core/tests/test_feedback_api.py
  • vektra-index/src/vektra_index/reindex.py
  • vektra-index/tests/test_reindex.py
  • vektra-shared/src/vektra_shared/errors.py
  • vektra-shared/tests/test_errors.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/debt-033-error-envelope

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses DEBT-033 by ensuring that all API error paths return the standard REQ-010 error envelope instead of bare FastAPI details, introducing several new error codes across components. The review feedback is highly constructive and identifies opportunities to improve code quality and consistency: specifically, registering the new error codes as constants in errors.py, mapping them in _CODE_STATUS_OVERRIDE, and using dedicated helper functions to construct the error envelopes rather than doing so inline at the raise sites. Additionally, the feedback suggests updating imports and test suites to verify these new helper functions and error codes.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread vektra-shared/src/vektra_shared/errors.py
Comment thread vektra-shared/src/vektra_shared/errors.py
Comment thread vektra-shared/src/vektra_shared/errors.py
Comment thread vektra-admin/src/vektra_admin/api.py Outdated
Comment thread vektra-admin/src/vektra_admin/api.py Outdated
Comment thread vektra-core/src/vektra_core/api.py Outdated
Comment thread vektra-shared/tests/test_errors.py
Comment thread vektra-shared/tests/test_errors.py
Comment thread vektra-shared/tests/test_errors.py
Comment thread vektra-shared/tests/test_errors.py
Address the review: promote ERR-ADMIN-008 to a constant and add
service_initializing(), query_pipeline_unavailable() and
key_store_unavailable() factories in vektra_shared.errors, then raise
through them instead of constructing the envelope inline (matching the
auth_* / conversation_* factory pattern already in that module). This
also removes the duplicated ERR-ADMIN-008 block in the health handler.
No status changes; the TRANSIENT codes still resolve to 503 via the
category default, so no _CODE_STATUS_OVERRIDE entries are needed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fvadicamo fvadicamo merged commit ba23889 into develop Jul 15, 2026
24 checks passed
@fvadicamo fvadicamo deleted the fix/debt-033-error-envelope branch July 15, 2026 08:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working component:admin vektra-admin component component:core vektra-core component component:index vektra-index component component:shared vektra-shared component documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant