Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(devserver): add x-bt-use-gateway to CORS allowed headers by cjgalione · Pull Request #119 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(devserver): add x-bt-use-gateway to CORS allowed headers by cjgalione · Pull Request #119 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(devserver): add x-bt-use-gateway to CORS allowed headers by cjgalione · Pull Request #119 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(devserver): add x-bt-use-gateway to CORS allowed headers by cjgalione · Pull Request #119 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(devserver): add x-bt-use-gateway to CORS allowed headers by cjgalione · Pull Request #119 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(devserver): add x-bt-use-gateway to CORS allowed headers by cjgalione · Pull Request #119 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(devserver): add x-bt-use-gateway to CORS allowed headers by cjgalione · Pull Request #119 · braintrustdata/braintrust-sdk-python · GitHub
Skip to content

fix(devserver): add x-bt-use-gateway to CORS allowed headers - #119

Merged
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header
Mar 23, 2026
Merged

fix(devserver): add x-bt-use-gateway to CORS allowed headers#119
Curtis Galione (cjgalione) merged 1 commit into
mainfrom
fix/devserver-cors-add-use-gateway-header

Conversation

@cjgalione

Copy link
Copy Markdown
Contributor

Summary

  • Add x-bt-use-gateway to ALLOWED_HEADERS in the Python devserver CORS config, matching what api-ts/src/cors.ts already allows
  • Add a test that verifies CORS preflight accepts this header

Context

The Braintrust Playground sends x-bt-use-gateway: true when gateway routing is enabled. The main data plane (api-ts) added this header to its CORS allowlist in Feb (commit ee5f4f65e0), but the Python SDK devserver was never updated to match.

This causes browsers to block preflight OPTIONS requests to any remote eval server built on braintrust.devserver, with an error like:

Request header field x-bt-use-gateway is not allowed by Access-Control-Allow-Headers

Multiple demo projects (pydantic-supervisor, langgraph-supervisor, google-adk-supervisor) independently worked around this by monkey-patching bt_cors.ALLOWED_HEADERS at startup. This fix addresses it at the source.

Test plan

  • New test test_cors_preflight_allows_gateway_header sends an OPTIONS request with x-bt-use-gateway and asserts it appears in the response's access-control-allow-headers
  • All existing devserver integration tests continue to pass

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ty ty

@cjgalione
Curtis Galione (cjgalione) merged commit 824861d into mainMar 23, 2026
32 of 33 checks passed
@cjgalione
Curtis Galione (cjgalione) deleted the fix/devserver-cors-add-use-gateway-header branch March 23, 2026 22:48
@AbhiPrasad

Copy link
Copy Markdown
Member

Sign up for freeto 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

@cjgalione@AbhiPrasad