Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/auth-misimport-runtime-error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/nextjs": patch
---

Improved error message when `auth` is accidentally imported from `@clerk/nextjs` instead of `@clerk/nextjs/server`. Previously, bundlers would show a generic `'auth' is not exported` error. Now, a clear runtime error points developers to the correct import path.
19 changes: 19 additions & 0 deletions packages/nextjs/src/__tests__/auth-misimport.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest';

import { auth } from '../server-only-stubs';

describe('auth misimport from @clerk/nextjs', () => {
it('throws a descriptive error when called as a function', () => {
expect(() => (auth as unknown as () => void)()).toThrow("Clerk: auth() was imported from '@clerk/nextjs'");
expect(() => (auth as unknown as () => void)()).toThrow("import { auth } from '@clerk/nextjs/server'");
});

it('throws a descriptive error when accessing a property', () => {
expect(() => (auth as unknown as Record<string, unknown>).protect).toThrow(
"Clerk: auth was imported from '@clerk/nextjs'",
);
expect(() => (auth as unknown as Record<string, unknown>).protect).toThrow(
"import { auth } from '@clerk/nextjs/server'",
);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,4 @@ export const Show = ComponentsModule.Show as ServerComponentsServerModuleTypes['
* The `auth` function is only available in server-side contexts:
* API Routes, Server Components, Server Actions, and Middleware.
*/
export declare const auth: never;
export { auth } from './server-only-stubs';
Copy link
Copy Markdown
Member

@Ephem Ephem May 7, 2026

Choose a reason for hiding this comment

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

Does this approach move the error from being a build time one to being a runtime one? I'm not sure we should do that, I'd rather take a less specific error at build time than a great one at runtime or else users risk deploying bugs to production before catching the error?

I didn't think much about feasibility or where the current message was coming from when I wrote the issue. :/

18 changes: 18 additions & 0 deletions packages/nextjs/src/server-only-stubs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Runtime stubs for server-only exports that are accidentally imported from the
* main `@clerk/nextjs` entry point. Each stub is a Proxy that throws a
* descriptive error pointing the developer to the correct import path.
*/

export const auth: never = new Proxy((() => {}) as never, {
apply() {
throw new Error(
`Clerk: auth() was imported from '@clerk/nextjs'. The auth() helper is a server-side function and must be imported from '@clerk/nextjs/server'.\n\nTo fix this, update your import:\n import { auth } from '@clerk/nextjs/server'`,
);
},
get() {
throw new Error(
`Clerk: auth was imported from '@clerk/nextjs'. The auth() helper is a server-side function and must be imported from '@clerk/nextjs/server'.\n\nTo fix this, update your import:\n import { auth } from '@clerk/nextjs/server'`,
);
},
});
Loading