Skip to content

fix: locale-sensitive header normalization#1941

Merged
jbeckwith-oai merged 1 commit into
mainfrom
codex/fix-locale-header-normalization
Jul 15, 2026
Merged

fix: locale-sensitive header normalization#1941
jbeckwith-oai merged 1 commit into
mainfrom
codex/fix-locale-header-normalization

Conversation

@jbeckwith-oai

Copy link
Copy Markdown
Contributor

Summary

Fixes #1928.

This updates buildHeaders to normalize header names to lowercase ASCII before passing them into Headers.delete() and Headers.append().

Root cause

The original issue reports OpenAI-Organization and OpenAI-Project becoming invalid header names like openaı-organization under a Turkish locale. Plain JavaScript String.prototype.toLowerCase() is not locale-sensitive in Node, so changing only the internal comparison key is not enough. The issue workaround points at the real failure mode: a bundled/runtime Headers implementation may normalize the mixed-case header name with Turkish locale rules when we call delete() or append() with the original name.

By handing Headers the SDK's already-normalized ASCII header name, we avoid depending on the runtime's header-name casing behavior.

Validation

  • pnpm exec jest tests/buildHeaders.test.ts --runInBand
  • env LANG=tr_TR.UTF-8 LC_ALL=tr_TR.UTF-8 pnpm exec jest tests/buildHeaders.test.ts --runInBand
  • pnpm exec jest tests/index.test.ts tests/lib/azure.test.ts tests/log.test.ts tests/lib/workload-identity.test.ts tests/lib/bedrock.test.ts tests/api-resources/webhooks.test.ts --runInBand
  • pnpm exec jest tests/buildHeaders.test.ts tests/api-resources/chat/completions/completions.test.ts --runInBand
  • pnpm exec jest tests/api-resources/beta/threads/threads.test.ts tests/api-resources/videos.test.ts --runInBand
  • pnpm exec prettier --check src/internal/headers.ts tests/buildHeaders.test.ts
  • pnpm exec eslint src/internal/headers.ts tests/buildHeaders.test.ts
  • pnpm exec tsc --noEmit
  • pnpm build

@jbeckwith-oai jbeckwith-oai changed the title [codex] Fix locale-sensitive header normalization fix: locale-sensitive header normalization Jun 15, 2026
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/fix-locale-header-normalization branch from 7147463 to 65ed8ad Compare June 15, 2026 17:26
@jbeckwith-oai
jbeckwith-oai requested a review from HAYDEN-OAI June 15, 2026 17:27
@jbeckwith-oai
jbeckwith-oai marked this pull request as ready for review June 15, 2026 17:30
@jbeckwith-oai
jbeckwith-oai requested a review from a team as a code owner June 15, 2026 17:30

@HAYDEN-OAI HAYDEN-OAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks good overall. thanks for the careful root-cause analysis and targeted coverage!

Comment thread src/internal/headers.ts
const lowerName = name.toLowerCase();
if (!seenHeaders.has(lowerName)) {
targetHeaders.delete(name);
targetHeaders.delete(lowerName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice fix, and the regression coverage for locale-sensitive Headers implementations is convincing. one edge case worth following up on: toLowerCase() performs full unicode case conversion, so an invalid name like cooKie becomes the valid cookie before Headers can reject it. validating the original name against the ascii http-token grammar before lowercasing would preserve the existing rejection behavior without reintroducing the turkish locale issue.

@openai-sdks

openai-sdks Bot commented Jul 14, 2026

Copy link
Copy Markdown

OkTest Summary

237/237 SDK tests passed in 11.119s for Node SDK PR #1941.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 164ms
tests/chat-completions-create.test.ts ✅ Passed 220ms
tests/chat-completions-stream.test.ts ✅ Passed 256ms
tests/files-content-binary.test.ts ✅ Passed 162ms
tests/files-create-multipart.test.ts ✅ Passed 156ms
tests/files-list-pagination.test.ts ✅ Passed 195ms
tests/initialize-config.test.ts ✅ Passed 218ms
tests/instance-isolation.test.ts ✅ Passed 116ms
tests/models-list.test.ts ✅ Passed 174ms
tests/responses-background-lifecycle.test.ts ✅ Passed 189ms
tests/responses-body-method-errors.test.ts ✅ Passed 371ms
tests/responses-cancel-timeout.test.ts ✅ Passed 203ms
tests/responses-cancel.test.ts ✅ Passed 231ms
tests/responses-compact-retries.test.ts ✅ Passed 249ms
tests/responses-compact.test.ts ✅ Passed 211ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 141ms
tests/responses-create-advanced.test.ts ✅ Passed 192ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.166s
tests/responses-create-errors.test.ts ✅ Passed 234ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 225ms
tests/responses-create-retries.test.ts ✅ Passed 355ms
tests/responses-create-stream-failures.test.ts ✅ Passed 260ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.226s
tests/responses-create-stream-wire.test.ts ✅ Passed 2.711s
tests/responses-create-stream.test.ts ✅ Passed 81ms
tests/responses-create-terminal-states.test.ts ✅ Passed 229ms
tests/responses-create-timeout.test.ts ✅ Passed 288ms
tests/responses-create.test.ts ✅ Passed 161ms
tests/responses-delete.test.ts ✅ Passed 281ms
tests/responses-input-items-errors.test.ts ✅ Passed 223ms
tests/responses-input-items-list.test.ts ✅ Passed 176ms
tests/responses-input-items-options.test.ts ✅ Passed 212ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 331ms
tests/responses-input-tokens-count.test.ts ✅ Passed 267ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.398s
tests/responses-not-found-errors.test.ts ✅ Passed 309ms
tests/responses-parse.test.ts ✅ Passed 195ms
tests/responses-retrieve-retries.test.ts ✅ Passed 242ms
tests/responses-retrieve.test.ts ✅ Passed 237ms
tests/responses-stored-method-errors.test.ts ✅ Passed 537ms
tests/retry-behavior.test.ts ✅ Passed 3.11s
tests/sdk-error-shape.test.ts ✅ Passed 312ms

View OkTest run #29451591405

SDK merge (45c6896397ca) · head (19c60d6731d7) · base (62554053803d) · OkTest (fd7a761c81c1)

@jbeckwith-oai
jbeckwith-oai merged commit 18e8c29 into main Jul 15, 2026
18 checks passed
@stainless-app stainless-app Bot mentioned this pull request Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

upstream Needs to be addressed in Stainless upstream

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: TypeError: Header name must be a valid HTTP token ["openaı-organization"] on Turkish Windows/Locale

2 participants