Skip to content

fix: respect user-specified User-Agent headers without modification#362

Merged
robert-j-y merged 2 commits intomainfrom
devin/1769545064-fix-user-agent-header-override
Jan 27, 2026
Merged

fix: respect user-specified User-Agent headers without modification#362
robert-j-y merged 2 commits intomainfrom
devin/1769545064-fix-user-agent-header-override

Conversation

@robert-j-y
Copy link
Contributor

@robert-j-y robert-j-y commented Jan 27, 2026

Description

Fixes #300 - When users provided a custom User-Agent header, the SDK was appending its identifier to it, resulting in unexpected behavior like my-app/1.0, ai-sdk/openrouter/x.x.x.

Before:

createOpenRouter({ headers: { 'User-Agent': 'my-app/1.0' } })
// Sent: "my-app/1.0, ai-sdk/openrouter/x.x.x"

After:

createOpenRouter({ headers: { 'User-Agent': 'my-app/1.0' } })
// Sent: "my-app/1.0"

The fix also addresses a case-sensitivity bug where User-Agent (capitalized) was not recognized as the same header as user-agent (lowercase), causing duplicate headers to be sent.

Key changes:

  • Added case-insensitive header lookup for User-Agent via findHeaderKey()
  • User-specified User-Agent headers are now used verbatim
  • SDK identifier is only added as default when no User-Agent is provided
  • Added normalizeHeaders() to properly handle all HeadersInit variants (Headers objects, array-of-tuples, plain objects)
  • Fixed removeUndefinedEntries to filter both null and undefined values (was only filtering null)
  • Added comprehensive unit tests (14 tests) for withUserAgentSuffix

Updates since last revision:

  • Added normalizeHeaders() function to handle Headers objects and array-of-tuples inputs (previously Object.entries() on a Headers object returned empty array, silently losing all headers)
  • Fixed removeUndefinedEntries to use value != null instead of value !== null to properly filter undefined values
  • Added tests for HeadersInit variants (Headers object, array-of-tuples)
  • Updated undefined test to verify key is actually removed from result object

For reviewers:

  • Verify the behavior change is acceptable (SDK identifier no longer appended when user provides User-Agent)
  • Review normalizeHeaders() handling of Headers objects and arrays
  • Note: removeUndefinedEntries is only used by withUserAgentSuffix, so the fix is isolated

Checklist

  • I have run pnpm stylecheck and pnpm typecheck
  • I have run pnpm test and all tests pass
  • I have added tests for my changes (if applicable)
  • I have updated documentation (if applicable)

Changeset

  • I have run pnpm changeset to create a changeset file

Link to Devin run: https://app.devin.ai/sessions/27723ec908ef4455be28e3c3c491b31e
Requested by: Robert Yeakel (@robert-j-y)

- Add case-insensitive lookup for User-Agent header
- When user provides User-Agent (any case), use it verbatim without SDK suffix
- Only add SDK identifier as default when no User-Agent is provided
- Add comprehensive tests for withUserAgentSuffix function

Fixes #300

Co-Authored-By: Robert Yeakel <robert.yeakel@openrouter.ai>
- Add normalizeHeaders() to properly handle Headers objects and array-of-tuples
- Fix removeUndefinedEntries to filter both null and undefined values
- Add tests for Headers object and array-of-tuples inputs
- Update test to verify undefined keys are actually removed from result

Co-Authored-By: Robert Yeakel <robert.yeakel@openrouter.ai>
@robert-j-y robert-j-y merged commit bd8794a into main Jan 27, 2026
2 checks passed
@robert-j-y robert-j-y deleted the devin/1769545064-fix-user-agent-header-override branch January 27, 2026 20:42
@github-actions github-actions bot mentioned this pull request Jan 27, 2026
kesavan-byte pushed a commit to osm-API/ai-sdk-provider that referenced this pull request Feb 13, 2026
…penRouterTeam#362)

* fix: respect user-specified User-Agent headers without modification

- Add case-insensitive lookup for User-Agent header
- When user provides User-Agent (any case), use it verbatim without SDK suffix
- Only add SDK identifier as default when no User-Agent is provided
- Add comprehensive tests for withUserAgentSuffix function

Fixes OpenRouterTeam#300

Co-Authored-By: Robert Yeakel <robert.yeakel@openrouter.ai>

* fix: handle all HeadersInit variants and fix removeUndefinedEntries

- Add normalizeHeaders() to properly handle Headers objects and array-of-tuples
- Fix removeUndefinedEntries to filter both null and undefined values
- Add tests for Headers object and array-of-tuples inputs
- Update test to verify undefined keys are actually removed from result

Co-Authored-By: Robert Yeakel <robert.yeakel@openrouter.ai>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
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.

Openrouter AI SDK provider overrides/silently rewrites user-specified headers

1 participant