From 42afcfdf67960a9fb9dad3bcb618beaa61ba416d Mon Sep 17 00:00:00 2001 From: Curtis Galione Date: Mon, 23 Mar 2026 14:56:06 -0700 Subject: [PATCH] fix(devserver): add x-bt-use-gateway to CORS allowed headers The Braintrust Playground sends x-bt-use-gateway when gateway routing is enabled. The api-ts CORS config already allows it, but the Python devserver's ALLOWED_HEADERS list was missing it, causing browsers to block preflight requests to remote eval servers with a CORS error. --- py/src/braintrust/devserver/cors.py | 1 + .../devserver/test_server_integration.py | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/py/src/braintrust/devserver/cors.py b/py/src/braintrust/devserver/cors.py index 0b60f4e1..9f920fbf 100644 --- a/py/src/braintrust/devserver/cors.py +++ b/py/src/braintrust/devserver/cors.py @@ -23,6 +23,7 @@ "x-bt-project-id", "x-bt-stream-fmt", "x-bt-use-cache", + "x-bt-use-gateway", "x-stainless-os", "x-stainless-lang", "x-stainless-package-version", diff --git a/py/src/braintrust/devserver/test_server_integration.py b/py/src/braintrust/devserver/test_server_integration.py index c5a803b7..e425001e 100644 --- a/py/src/braintrust/devserver/test_server_integration.py +++ b/py/src/braintrust/devserver/test_server_integration.py @@ -87,6 +87,28 @@ def test_devserver_health_check(client): assert response.text == "Hello, world!" +def test_cors_preflight_allows_gateway_header(client): + """Test that CORS preflight accepts x-bt-use-gateway header. + + The Braintrust Playground sends this header when gateway routing is + enabled. If it is missing from the devserver's allowed-headers list + the browser blocks the actual request with a CORS error. + """ + response = client.options( + "/eval", + headers={ + "origin": "https://www.braintrust.dev", + "access-control-request-method": "POST", + "access-control-request-headers": "x-bt-use-gateway", + }, + ) + assert response.status_code == 200 + allowed = response.headers.get("access-control-allow-headers", "") + assert "x-bt-use-gateway" in allowed, ( + f"x-bt-use-gateway not found in access-control-allow-headers: {allowed}" + ) + + @pytest.mark.vcr def test_devserver_list_evaluators(client, api_key, org_name): """Test listing evaluators endpoint."""