{"repo":"NousResearch/hermes-agent","public_id":"3378","display_label":"CORS headers missing on SSE streaming endpoints","summary":"Bug reports and fixes addressing missing CORS headers on Server-Sent Events (SSE) streaming endpoints, which causes cross-origin requests to fail. Multiple fix attempts target the /v1/runs/{run_id}/events endpoint and general streaming responses.","subsystem":"gateway","counts":{"members":3,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":1},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":3573,"merged_at":"2026-03-28T20:38:30+00:00"},"resolution":{"state":"unresolved","by":null},"freshness":{"state":"stale","last_verified_at":"2026-03-28T20:38:30+00:00","is_stale":true},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.6666666666666666},"fix_edges":[{"issue_number":3378,"pr_number":3573,"tier":"verified","basis":"superseded_ref","confidence":0.9,"recoverable_from_timeline":false,"pr_merged_at":"2026-03-28T20:38:30+00:00"}],"members":[{"kind":"issue","number":3378,"title":"[Bug]: headers missing on streaming responses (stream:true)","url":null,"state":"closed"},{"kind":"pr","number":3381,"title":"fix(api-server): add CORS headers to streaming SSE responses","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#3573","number":3573}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":3573,"title":"fix(api-server): add CORS headers to streaming SSE responses","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["gateway/platforms/api_server.py"],"fix_hunks":[{"file":"gateway/platforms/api_server.py","hunks":["@@ -582,10 +582,14 @@ async def _write_sse_chat_completion(\n         \"\"\"\n         import queue as _q\n \n-        response = web.StreamResponse(\n-            status=200,\n-            headers={\"Content-Type\": \"text/event-stream\", \"Cache-Control\": \"no-cache\"},\n-        )\n+        sse_headers = {\"Content-Type\": \"text/event-stream\", \"Cache-Control\": \"no-cache\"}\n+        # CORS middleware can't inject headers into StreamResponse after\n+        # prepare() flushes them, so resolve CORS headers up front.\n+        origin = request.headers.get(\"Origin\", \"\")\n+        cors = self._cors_headers_for_origin(origin) if origin else None\n+        if cors:\n+            sse_headers.update(cors)\n+        response = web.StreamResponse(status=200, headers=sse_headers)\n         await response.prepare(request)\n \n         try:\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}