Preliminary Checks
Reproduction
https://github.com/sadnansami/xcoach-clerk-middleware-issue
Publishable key
pk_test_YnJhdmUtcGVyY2gtNy5jbGVyay5hY2NvdW50cy5kZXYk
Description
Package: @clerk/astro
Versions:
@clerk/astro: latest
astro: v7
Steps to reproduce:
- Set up an Astro project with
@clerk/astro
- Add
clerkMiddleware() as the Astro onRequest handler in src/middleware.ts
- Create any Astro API route that reads the request body (e.g.
await request.json())
- Send a POST request to that route
Expected behavior:
clerkMiddleware() should authenticate the request without consuming it, so anything downstream — an Astro API route, an adapter, or any other middleware — can still read the body.
Actual behavior:
Anything that tries to read the request body after clerkMiddleware() runs throws:
TypeError: Body has already been used. It can only be used once. Use tee() first if you need to read it twice.
clerkMiddleware() drains the request body during authentication. This is not specific to any adapter or runtime — it affects any downstream consumer of the request body.
Related:
This exact bug was already fixed for @clerk/tanstack-react-start in PR #7020 (Oct 2025), which resolved issue #7019. The fix wraps the incoming request with patchRequest into a ClerkRequest to avoid consuming the body, taking inspiration from the existing implementation in @clerk/react-router.
The same fix needs to be ported to @clerk/astro's clerkMiddleware. The pattern and precedent are already established in the codebase.
Environment
System:
OS: Windows 11 10.0.26200
CPU: (12) x64 AMD Ryzen 5 4600H with Radeon Graphics
Memory: 6.19 GB / 23.87 GB
Binaries:
Node: 24.14.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.22 - C:\Users\S. Adnan Sami\AppData\Local\pnpm\yarn.CMD
npm: 10.8.3 - C:\Program Files\nodejs\npm.CMD
pnpm: 9.11.0 - C:\Program Files\nodejs\pnpm.CMD
bun: 1.3.11 - C:\Users\S. Adnan Sami\.bun\bin\bun.EXE
Deno: 2.7.5 - C:\Users\S. Adnan Sami\.deno\bin\deno.EXE
Browsers:
Chrome: 150.0.7871.129
Edge: Chromium (150.0.4078.83)
Internet Explorer: 11.0.26100.8115
npmPackages:
@astrojs/alpinejs: ^1.0.0 => 1.0.0
@astrojs/cloudflare: ^14.1.3 => 14.1.3
@astrojs/node: ^11.0.2 => 11.0.2
@clerk/astro: ^3.4.19 => 3.4.19
@tailwindcss/vite: ^4.3.2 => 4.3.2
@types/alpinejs: ^3.13.11 => 3.13.11
@types/node: ^26.1.1 => 26.1.1
agents: ^0.17.4 => 0.17.4
alpinejs: ^3.15.12 => 3.15.12
astro: ^7.0.9 => 7.0.9
clsx: ^2.1.1 => 2.1.1
cuelume: ^0.1.2 => 0.1.2
hono: ^4.12.30 => 4.12.30
hono-agents: ^3.0.11 => 3.0.11
sonner: ^2.0.7 => 2.0.7
tailwind-merge: ^3.6.0 => 3.6.0
tailwindcss: ^4.3.2 => 4.3.2
tailwindcss-motion: ^1.1.1 => 1.1.1
tw-animate-css: ^1.4.0 => 1.4.0
wrangler: ^4.110.0 => 4.111.0
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/sadnansami/xcoach-clerk-middleware-issue
Publishable key
pk_test_YnJhdmUtcGVyY2gtNy5jbGVyay5hY2NvdW50cy5kZXYk
Description
Package:
@clerk/astroVersions:
@clerk/astro: latestastro: v7Steps to reproduce:
@clerk/astroclerkMiddleware()as the AstroonRequesthandler insrc/middleware.tsawait request.json())Expected behavior:
clerkMiddleware()should authenticate the request without consuming it, so anything downstream — an Astro API route, an adapter, or any other middleware — can still read the body.Actual behavior:
Anything that tries to read the request body after
clerkMiddleware()runs throws:clerkMiddleware()drains the request body during authentication. This is not specific to any adapter or runtime — it affects any downstream consumer of the request body.Related:
This exact bug was already fixed for
@clerk/tanstack-react-startin PR #7020 (Oct 2025), which resolved issue #7019. The fix wraps the incoming request withpatchRequestinto aClerkRequestto avoid consuming the body, taking inspiration from the existing implementation in@clerk/react-router.The same fix needs to be ported to
@clerk/astro'sclerkMiddleware. The pattern and precedent are already established in the codebase.Environment
System: OS: Windows 11 10.0.26200 CPU: (12) x64 AMD Ryzen 5 4600H with Radeon Graphics Memory: 6.19 GB / 23.87 GB Binaries: Node: 24.14.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.22 - C:\Users\S. Adnan Sami\AppData\Local\pnpm\yarn.CMD npm: 10.8.3 - C:\Program Files\nodejs\npm.CMD pnpm: 9.11.0 - C:\Program Files\nodejs\pnpm.CMD bun: 1.3.11 - C:\Users\S. Adnan Sami\.bun\bin\bun.EXE Deno: 2.7.5 - C:\Users\S. Adnan Sami\.deno\bin\deno.EXE Browsers: Chrome: 150.0.7871.129 Edge: Chromium (150.0.4078.83) Internet Explorer: 11.0.26100.8115 npmPackages: @astrojs/alpinejs: ^1.0.0 => 1.0.0 @astrojs/cloudflare: ^14.1.3 => 14.1.3 @astrojs/node: ^11.0.2 => 11.0.2 @clerk/astro: ^3.4.19 => 3.4.19 @tailwindcss/vite: ^4.3.2 => 4.3.2 @types/alpinejs: ^3.13.11 => 3.13.11 @types/node: ^26.1.1 => 26.1.1 agents: ^0.17.4 => 0.17.4 alpinejs: ^3.15.12 => 3.15.12 astro: ^7.0.9 => 7.0.9 clsx: ^2.1.1 => 2.1.1 cuelume: ^0.1.2 => 0.1.2 hono: ^4.12.30 => 4.12.30 hono-agents: ^3.0.11 => 3.0.11 sonner: ^2.0.7 => 2.0.7 tailwind-merge: ^3.6.0 => 3.6.0 tailwindcss: ^4.3.2 => 4.3.2 tailwindcss-motion: ^1.1.1 => 1.1.1 tw-animate-css: ^1.4.0 => 1.4.0 wrangler: ^4.110.0 => 4.111.0