Skip to content

fix(api): CORS headers on 5xx + 404 (not 500) for malformed cloud ids#34

Merged
WayforthOfficial merged 1 commit into
mainfrom
fix/cors-on-errors-and-uuid-guard
Jun 21, 2026
Merged

fix(api): CORS headers on 5xx + 404 (not 500) for malformed cloud ids#34
WayforthOfficial merged 1 commit into
mainfrom
fix/cors-on-errors-and-uuid-guard

Conversation

@WayforthOfficial

Copy link
Copy Markdown
Owner

1. CORS on error responses. Unhandled 500s render in ServerErrorMiddleware (outside CORSMiddleware), so every 5xx reached the browser with no Access-Control-* headers — surfacing as a generic CORS/"Load failed" error that masked every server error platform-wide. Added an Exception handler that returns a clean JSON 500 with the allow-credentials CORS contract (echoes the request Origin iff allow-listed). Origins are now one shared constant.

2. Malformed id → 404, not 500. GET /cloud/agents/{id} and /{id}/runs threw an unhandled asyncpg invalid input syntax for type uuid on a non-UUID id (e.g. "undefined"). _get_agent_or_404 now validates the id → 404; run-by-id endpoints guard run_id → 404.

Verified in isolation: forced 500 → Access-Control-Allow-Origin: https://wayforth.io; bad id → 404.

🤖 Generated with Claude Code

1. CORS on error responses. Starlette renders unhandled 500s in
   ServerErrorMiddleware, which sits OUTSIDE CORSMiddleware — so every gateway
   5xx reached the browser with no Access-Control-* headers and looked like a
   CORS failure ("Load failed"), masking the real error platform-wide. Added an
   Exception (500) handler that returns a clean JSON 500 and re-attaches the
   allow-credentials CORS contract (echoes the request Origin iff allow-listed).
   Origins are now a single shared constant used by both CORSMiddleware and the
   handler. HTTPExceptions already get CORS (handled inside ExceptionMiddleware).

2. Malformed cloud id -> 404, not 500. GET /cloud/agents/{id} and /{id}/runs
   threw an unhandled asyncpg "invalid input syntax for type uuid" (e.g. the
   frontend sending "undefined") -> 500. _get_agent_or_404 now validates the id
   is a UUID and returns 404 agent_not_found; the run-by-id endpoints
   (status/logs/cancel) likewise guard run_id -> 404 run_not_found. Every
   agent-by-id endpoint already routes through _get_agent_or_404, so all are
   covered.

Verified in isolation: a forced 500 returns Access-Control-Allow-Origin:
https://wayforth.io; a bad id returns 404 (also with CORS).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@WayforthOfficial WayforthOfficial merged commit e741a58 into main Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants