Skip to content

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Feb 11, 2026

Summary

  • auth.protect() in middleware now returns 401 (Unauthorized) instead of 404 (Not Found) when the user is unauthenticated and the request is a server action
  • Server action requests are identified by the existing isServerActionRequest() helper (checks next-url + next-action/text/x-component/multipart/form-data headers)
  • Clients can now catch 401 responses and trigger sign-in flows instead of getting a misleading 404

How it works

Added a check for server action requests in the handleUnauthenticated closure in protect.ts, between the existing isPageRequest check and the notFound() fallback:

if (isServerActionRequest(request)) {
  return unauthorized();
}

The unauthorized callback is already passed into createProtect by both callers (middleware and server components), so the existing 401 error handling path works without any other changes.

Test plan

  • Added test: "returns 401 when protect is called, the user is signed out, and the request is a server action"
  • Existing test for non-page requests (without server action headers) still returns 404 via notFound()
  • pnpm build --filter=@clerk/nextjs passes
  • pnpm vitest run packages/nextjs/src/server/__tests__/clerkMiddleware.test.ts passes (104/104)

Summary by CodeRabbit

  • Breaking Changes

    • auth.protect() now returns 401 Unauthorized instead of 404 Not Found for unauthenticated server action requests
  • Documentation

    • Added migration guide with code examples for updating error handling in server actions

@changeset-bot
Copy link

changeset-bot bot commented Feb 11, 2026

🦋 Changeset detected

Latest commit: cab1547

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/nextjs Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Feb 11, 2026

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Feb 11, 2026 1:21pm

Request Review

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 11, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7820

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7820

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7820

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7820

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7820

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7820

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7820

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7820

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7820

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7820

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7820

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7820

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7820

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7820

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7820

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7820

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7820

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7820

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7820

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7820

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7820

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7820

commit: cab1547

Copy link
Member

@wobsoriano wobsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nicee

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a breaking change in the Clerk Next.js package where unauthenticated server action requests handled by auth.protect() now return HTTP 401 (Unauthorized) instead of 404 (Not Found). The implementation detects server action requests via specific request headers and routes them to an unauthorized response. A test case validates this behavior, and a changeset documents the major version bump. Upgrade documentation provides migration guidance for client-side error handling that depends on the response status.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: auth.protect() now returns 401 for unauthenticated server action requests, which is the primary purpose of this PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


No actionable comments were generated in the recent review. 🎉


Comment @coderabbitai help to get the list of available commands and usage tips.

@jacekradko jacekradko requested a review from brkalow February 11, 2026 16:33
@jacekradko jacekradko merged commit 4be764f into main Feb 12, 2026
39 of 41 checks passed
@jacekradko jacekradko deleted the jacek/protect-server-action-401 branch February 12, 2026 04:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants