Skip to content

fix(core): preserve string-shorthand endpoint URL when merging a partial config override - #13493

Open
HeroCode007 wants to merge 1 commit into
nextauthjs:mainfrom
HeroCode007:fix/merge-string-endpoint-shorthand
Open

HeroCode007 wants to merge 1 commit into
nextauthjs:mainfrom
HeroCode007:fix/merge-string-endpoint-shorthand

Conversation

@HeroCode007

Copy link
Copy Markdown

☕️ Reasoning

authorization, token, and userinfo accept a string shorthand for just the endpoint URL (e.g. Spotify's default: "https://accounts.spotify.com/authorize?scope=user-read-email"). When a user overrides only part of that config — e.g. authorization: { params: { scope } }, without a new url, exactly as the docs for customizing a built-in OAuth provider recommend — merge() sees a string default next to an object override and can't combine them, so it silently resets the target to {} and discards the string default entirely. The base URL is lost, and normalizeEndpoint falls back to its hardcoded placeholder (https://authjs.dev) instead of the real provider endpoint.

This is the scenario originally reported in #9448 (Discord provider, scope override). A related direction of this bug (object default overridden by a string) was fixed in #11685, but that fix doesn't cover this case — I confirmed it's still reproducible today, straight from main:

// packages/core/src/providers/spotify.ts default:
authorization: "https://accounts.spotify.com/authorize?scope=user-read-email"

// user override, per the docs:
authorization: { params: { scope: "user-read-email playlist-read-private" } }

// => before this fix, final authorization URL:
// https://authjs.dev/?scope=user-read-email+playlist-read-private

Fix

Rather than changing merge() itself (which is a generic deep-merge utility with no URL-specific knowledge), this promotes a string-shorthand default to { url } before merging, in parseProviders, which already owns the domain knowledge that authorization/token/userinfo support this shorthand. Both sides of the merge are then objects, so merge() combines them correctly instead of discarding one.

After the fix, the same scenario produces:

https://accounts.spotify.com/authorize?scope=user-read-email+playlist-read-private

Verified this doesn't affect the two existing merge-direction cases already covered in merge.test.ts (string target fully replaced by an object override that includes its own url, and object target replaced by a string override).

🧢 Checklist

  • Documentation
  • Tests
  • Ready to be merged

🎫 Affected issues

Fixes: #9448

…ial config override

`authorization`, `token`, and `userinfo` accept a string shorthand for
just the endpoint URL (e.g. Spotify's default:
"https://accounts.spotify.com/authorize?scope=user-read-email"). When a
user overrides only part of that config — e.g.
`authorization: { params: { scope } }`, without a new `url`, exactly as
the docs for customizing a provider recommend — `merge()` sees a string
default next to an object override, can't combine them, and silently
discards the string default entirely. The base URL is lost, and the
final authorization request falls back to a hardcoded placeholder
domain instead of the real provider endpoint.

Promote the string default to `{ url }` before merging, so both sides
are objects and `merge()` combines them instead of discarding one.

Verified end-to-end with parseProviders() + Spotify's real default
config: before this change the resulting authorization URL was
"https://authjs.dev/?scope=...", after it's
"https://accounts.spotify.com/authorize?scope=...".

Fixes: nextauthjs#9448

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
auth-docs Ready Ready Preview Sep 6, 2026 6:14pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
next-auth-docs Ignored Ignored Preview Sep 6, 2026 6:14pm UTC

Request Review

@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the authjs Team on Vercel.

A member of the Team first needs to authorize it.

This branch was successfully deployed

1 active deployment
Preview – auth-docs — 788ce168 Deployed Sep 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Refers to `@auth/core`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Next Auth [v5.0.0-beta.4] Middleware and Scope not working

1 participant