diff --git a/packages/client/src/client/auth.ts b/packages/client/src/client/auth.ts index 1a021be18..0391e35e9 100644 --- a/packages/client/src/client/auth.ts +++ b/packages/client/src/client/auth.ts @@ -1439,6 +1439,10 @@ export async function executeTokenRequest( applyClientAuthentication(authMethod, clientInformation as OAuthClientInformation, headers, tokenRequestParams); } + // Ensure Content-Type is always form-urlencoded for the token endpoint (OAuth 2.1 §3.2). + // Some addClientAuthentication implementations may have inadvertently set a different value. + headers.set('Content-Type', 'application/x-www-form-urlencoded'); + const response = await (fetchFn ?? fetch)(tokenUrl, { method: 'POST', headers, diff --git a/packages/core/src/types/schemas.ts b/packages/core/src/types/schemas.ts index c8f0c9978..a8cf1d77a 100644 --- a/packages/core/src/types/schemas.ts +++ b/packages/core/src/types/schemas.ts @@ -119,8 +119,18 @@ export const ResultSchema = z.looseObject({ /** * A uniquely identifying ID for a request in JSON-RPC. - */ -export const RequestIdSchema = z.union([z.string(), z.number().int()]); + * Rejects integers outside Number.MAX_SAFE_INTEGER to prevent JavaScript + * Map/Object key precision loss that causes server hangs (Issue #1765). + */ +export const RequestIdSchema = z.union([ + z.string(), + z + .number() + .int() + .refine((n) => Math.abs(n) <= Number.MAX_SAFE_INTEGER, { + message: `Request ID must be a safe integer (|id| ≤ ${Number.MAX_SAFE_INTEGER})` + }) +]); /** * A request that expects a response.