[beta] Error in Vercel from `Request` global mismatch
itsMapleLeaf opened this issue · 2 comments
Preliminary Checks
- I have reviewed the documentation: https://clerk.com/docs
- I have searched for existing issues: https://github.com/clerk/javascript/issues
- I have not already reached out to Clerk support via email or Discord (if you have, no need to open an issue here)
- This issue is not a question, general help request, or anything other than a bug report directly related to Clerk. Please ask questions in our Discord community: https://clerk.com/discord.
Reproduction
https://github.com/itsMapleLeaf/clerk-beta-remix-vercel-bug
Publishable key
pk_test_ZnJhbmstcHVnLTkwLmNsZXJrLmFjY291bnRzLmRldiQ
Description
Steps to reproduce:
git clone https://github.com/itsMapleLeaf/clerk-beta-remix-vercel-bug
cd clerk-beta-remix-vercel-bug
npx vercel deploy
Expected behavior:
A working Vercel deployment
Actual behavior:
The app crashes at runtime with the following error:
TypeError: Failed to parse URL from [object Request]
at new Request (node:internal/deps/undici/undici:5855:19)
at new ClerkRequest (/var/task/node_modules/@clerk/backend/dist/internal.js:2213:5)
... 6 lines matching cause stack trace ...
at runHandler (/var/task/node_modules/@remix-run/server-runtime/node_modules/@remix-run/router/dist/router.cjs.js:4110:26)
at callLoaderOrAction (/var/task/node_modules/@remix-run/server-runtime/node_modules/@remix-run/router/dist/router.cjs.js:4166:22) {
[cause]: TypeError: Invalid URL
at new URL (node:internal/url:775:36)
at new Request (node:internal/deps/undici/undici:5853:25)
at new ClerkRequest (/var/task/node_modules/@clerk/backend/dist/internal.js:2213:5)
at createClerkRequest (/var/task/node_modules/@clerk/backend/dist/internal.js:2247:54)
at loadOptions (/var/task/node_modules/@clerk/remix/dist/ssr/loadOptions.js:34:63)
at rootAuthLoader (/var/task/node_modules/@clerk/remix/dist/ssr/rootAuthLoader.js:33:60)
at loader$1 (file:///var/task/build/server/nodejs-eyJydW50aW1lIjoibm9kZWpzIn0/index.js:227:28)
at Object.callRouteLoaderRR (/var/task/node_modules/@remix-run/server-runtime/dist/data.js:52:22)
at commonRoute.loader (/var/task/node_modules/@remix-run/server-runtime/dist/routes.js:54:20)
at runHandler (/var/task/node_modules/@remix-run/server-runtime/node_modules/@remix-run/router/dist/router.cjs.js:4110:26) {
code: 'ERR_INVALID_URL',
input: '[object Request]'
}
}
The reproduction here is specifically in the case of Vercel + Remix, but I think the root of the issue is the [ClerkRequest](https://github.com/clerk/javascript/blob/178974f9fc562410f8bcc6f83da0484cac961211/packages/backend/src/tokens/clerkRequest.ts#L7)
class.
Here's what happens:
@clerk/backend
is imported, and this class is defined, extending theRequest
global from Node.js/undici- Vercel (or any other naïve server file) calls
[installGlobals()](https://github.com/vercel/vercel/blob/326fe0f0e647a80ef504ca4035c6bc3c206f43d6/packages/remix/defaults/server-node.mjs#L7)
and replaces the global[Request](https://github.com/vercel/vercel/blob/326fe0f0e647a80ef504ca4035c6bc3c206f43d6/packages/remix/defaults/server-node.mjs#L7)
with the one from Remix - At runtime, a Remix
Request
gets passed into aClerkRequest
- Via
super()
,ClerkRequest
passes the RemixRequest
to the Node.jsRequest
- Node.js doesn't recognize the request instance, so it blindly tries to stringify it and parse it as URL
- 💥
If possible, the code should change to not rely on a class whose identity is locked at definition time.
Environment
System:
OS: Windows 11 10.0.22631
CPU: (16) x64 AMD Ryzen 7 2700X Eight-Core Processor
Memory: 12.44 GB / 31.94 GB
Binaries:
Node: 20.11.1 - ~\scoop\apps\nvm\current\nodejs\nodejs\node.EXE
Yarn: 1.22.19 - ~\scoop\apps\nvm\current\nodejs\nodejs\yarn.CMD
npm: 10.2.4 - ~\scoop\apps\nvm\current\nodejs\nodejs\npm.CMD
pnpm: 8.15.4 - ~\scoop\apps\nvm\current\nodejs\nodejs\pnpm.CMD
bun: 1.1.0 - ~\.bun\bin\bun.EXE
Browsers:
Edge: Chromium (122.0.2365.92)
Internet Explorer: 11.0.22621.1
npmPackages:
@ariakit/react: ^0.4.4 => 0.4.5
@biomejs/biome: 1.6.3 => 1.6.3
@clerk/remix: 4.0.0-beta.39 => 4.0.0-beta.39
@clerk/themes: 2.0.0-beta.8 => 2.0.0-beta.8
@floating-ui/react: 0.26.9 => 0.26.9
@floating-ui/react-dom: 2.0.8 => 2.0.8
@fontsource-variable/nunito: 5.0.18 => 5.0.18
@remix-run/dev: ^2.8.1 => 2.8.1
@remix-run/node: ^2.8.1 => 2.8.1
@remix-run/react: ^2.8.1 => 2.8.1
@remix-run/serve: ^2.8.1 => 2.8.1
@tailwindcss/container-queries: 0.1.1 => 0.1.1
@total-typescript/ts-reset: 0.5.1 => 0.5.1
@types/lodash-es: 4.17.12 => 4.17.12
@types/node: ^20.12.2 => 20.12.2
@types/react: ^18.2.70 => 18.2.73
@types/react-dom: ^18.2.22 => 18.2.23
@vercel/remix: 2.8.1 => 2.8.1
colorjs.io: 0.5.0 => 0.5.0
convex: 1.10.0 => 1.10.0
convex-helpers: 0.1.27 => 0.1.27
date-fns: 3.6.0 => 3.6.0
dotenv-cli: 7.4.1 => 7.4.1
hash-wasm: 4.11.0 => 4.11.0
isbot: ^5.1.2 => 5.1.3
lodash-es: 4.17.21 => 4.17.21
lucide-react: 0.363.0 => 0.363.0
npm-run-all: 4.1.5 => 4.1.5
prettier: 3.2.5 => 3.2.5
prettier-plugin-jsdoc: 1.3.0 => 1.3.0
prettier-plugin-tailwindcss: 0.5.12 => 0.5.12
random-word-slugs: 0.1.7 => 0.1.7
react: 19.0.0-canary-95e6f032c-20240401 => 19.0.0-canary-95e6f032c-20240401
react-dom: 19.0.0-canary-95e6f032c-20240401 => 19.0.0-canary-95e6f032c-20240401
react-textarea-autosize: 8.5.3 => 8.5.3
react-virtuoso: 4.7.4 => 4.7.4
remix-flat-routes: 0.6.4 => 0.6.4
remix-routes: 1.7.2 => 1.7.2
rollup-plugin-visualizer: 5.12.0 => 5.12.0
tailwind-merge: 2.2.2 => 2.2.2
tailwindcss: 3.4.1 => 3.4.1
tailwindcss-animate: ^1.0.7 => 1.0.7
ts-dedent: 2.2.0 => 2.2.0
typescript: 5.4.3 => 5.4.3
vite: ^5.2.6 => 5.2.7
vite-plugin-inspect: 0.8.3 => 0.8.3
zod: 3.22.4 => 3.22.4
Hi, thanks for the detailed issue! We're collecting all Beta feedback in this GitHub discussion, so please repost your issue there. Thanks!
BTW, in order to achieve the expected functionality, I thoroughly reviewed the source code of both clerk/node-sdk
and clerk/express
. Through this process, I discovered that we need to transform the IncomingMessage
to a Request
object instance, as in the authenticateRequest. Eventually, following this approach I resolved the issue successfully.