I am a beginner/intermediate developer attempting to create a NextJS 14 powered app for a friend of mine, but I seem to keep running into the same problem.
I am loosely following this tutorial by CodeWithAntonio with some slight tweaks to work for me. I have already tried going back through the tutorial more times than I can count to find a fix, but seemingly I cannot find one.
I am using NextJS 14 App-directory, with a Neon database and the Prisma adapter due to some incompatibilities with DrizzleORM in its current state.
This is my auth.ts file in the root directory:
import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { db } from "@/lib/db";
import authConfig from "@/auth.config";
import { getUserById } from "@/lib/user";
import { UserRole } from "@prisma/client";
export const {
handlers: { GET, POST },
auth,
signIn,
signOut,
} = NextAuth({
pages: {
signIn: "/auth/login",
error: "/auth/error",
},
callbacks: {
async signIn({ user, account }) {
if (account?.provider !== "credentials") return true;
return true;
},
async session({ token, session }) {
if (token.sub && session.user) {
session.user.id = token.sub;
}
if (token.role && session.user) {
session.user.role = token.role as UserRole;
}
return session;
},
async jwt({ token }) {
if (!token.sub) return token;
// this grabs the data from the db on the user from the user id on the token
const existingUser = await getUserById(token.sub);
if (!existingUser) return token;
token.role = existingUser.role;
return token;
},
},
adapter: PrismaAdapter(db),
session: { strategy: "jwt", maxAge: 60 * 60 * 24 },
...authConfig,
});
and this is my auth.config.ts file also in the root:
import bcrypt from "bcryptjs";
import type { NextAuthConfig } from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { LoginSchema } from "@/schemas";
import { getUserByEmail } from "./lib/user";
export default {
providers: [
Credentials({
async authorize(credentials) {
const validatedFields = LoginSchema.safeParse(credentials);
if (validatedFields.success) {
const { email, password } = validatedFields.data;
// gets the user data from the db by email
const user = await getUserByEmail(email);
if (!user || !user.password) return null;
const passwordsMatch = await bcrypt.compare(password, user.password);
if (passwordsMatch) return user;
return null;
}
return null;
},
}),
],
} satisfies NextAuthConfig;
I believe these are all the files useful to the error which looks like this for context:
Read more at https://errors.authjs.dev/#credentialssignin
[auth][error] CallbackRouteError: Read more at https://errors.authjs.dev#callbackrouteerror
[auth][cause]: Error
at Module.callback (webpack-internal:///(action-browser)/./node_modules/@auth/core/lib/actions/callback/index.js:226:23)
at async AuthInternal (webpack-internal:///(action-browser)/./node_modules/@auth/core/lib/index.js:66:24)
at async Auth (webpack-internal:///(action-browser)/./node_modules/@auth/core/index.js:126:34)
at async signIn (webpack-internal:///(action-browser)/./node_modules/next-auth/lib/actions.js:51:17)
at async $$ACTION_0 (webpack-internal:///(action-browser)/./actions/login.ts:46:9)
at async F:lng-v3node_modulesnextdistcompilednext-serverapp-page.runtime.dev.js:39:418
at async rw (F:lng-v3node_modulesnextdistcompilednext-serverapp-page.runtime.dev.js:38:7978)
at async r4 (F:lng-v3node_modulesnextdistcompilednext-serverapp-page.runtime.dev.js:41:1251)
at async doRender (F:lng-v3node_modulesnextdistserverbase-server.js:1438:30)
at async cacheEntry.responseCache.get.routeKind (F:lng-v3node_modulesnextdistserverbase-server.js:1599:28)
at async DevServer.renderToResponseWithComponentsImpl (F:lng-v3node_modulesnextdistserverbase-server.js:1507:28)
at async DevServer.renderPageComponent (F:lng-v3node_modulesnextdistserverbase-server.js:1931:24)
at async DevServer.renderToResponseImpl (F:lng-v3node_modulesnextdistserverbase-server.js:1969:32)
at async DevServer.pipeImpl (F:lng-v3node_modulesnextdistserverbase-server.js:920:25)
at async NextNodeServer.handleCatchallRenderRequest (F:lng-v3node_modulesnextdistservernext-server.js:272:17)
at async DevServer.handleRequestImpl (F:lng-v3node_modulesnextdistserverbase-server.js:816:17)
at async F:lng-v3node_modulesnextdistserverdevnext-dev-server.js:339:20
at async Span.traceAsyncFn (F:lng-v3node_modulesnextdisttracetrace.js:154:20)
at async DevServer.handleRequest (F:lng-v3node_modulesnextdistserverdevnext-dev-server.js:336:24)
at async invokeRender (F:lng-v3node_modulesnextdistserverlibrouter-server.js:174:21)
at async handleRequest (F:lng-v3node_modulesnextdistserverlibrouter-server.js:353:24)
at async requestHandlerImpl (F:lng-v3node_modulesnextdistserverlibrouter-server.js:377:13)
at async Server.requestListener (F:lng-v3node_modulesnextdistserverlibstart-server.js:141:13)
[auth][details]: {
"provider": "credentials"
}
This is the server action (login.ts) that actually logs the user in and is called directly from the login form:
"use server";
import * as z from "zod";
import { LoginSchema } from "@/schemas";
import { signIn } from "@/auth";
import { DEFAULT_LOGIN_REDIRECT } from "@/routes";
import { AuthError } from "next-auth";
import { getUserByEmail } from "@/lib/user";
import { generateVerificationToken } from "@/lib/tokens";
export const login = async (values: z.infer<typeof LoginSchema>) => {
const validatedFields = LoginSchema.safeParse(values);
if (!validatedFields.success) {
return { error: "Invalid fields!" };
}
const { email, password } = validatedFields.data;
// gets user data from the db by email
const existingUser = await getUserByEmail(email);
if (!existingUser || !existingUser.email || !existingUser.password) {
return { error: "Your email and/or password are incorrect." };
}
if (!existingUser.email_verified) {
// creates and returns a verification token for the user from the db
const verificationToken = await generateVerificationToken(
existingUser.email
);
return { success: "Verification email sent!" };
}
try {
await signIn("credentials", {
email,
password,
// currently just set to /settings page
redirectTo: DEFAULT_LOGIN_REDIRECT,
});
} catch (error) {
// this is what seems to be returning the error message "CallbackRouteError"
console.log(error);
if (error instanceof AuthError) {
switch (error.type) {
case "CredentialsSignin":
return { error: "Your email and/or password are incorrect." };
default:
return { error: "Something went wrong!" };
}
}
throw error;
}
};
When using the signIn() function through the server action (login.ts) in my login form passing the email and password in string format, I get an error console logged saying:
Read more at https://errors.authjs.dev/#credentialssignin
[auth][error] CallbackRouteError: Read more at https://errors.authjs.dev#callbackrouteerror
[auth][cause]: Error
at Module.callback (webpack-internal:///(action-browser)/./node_modules/@auth/core/lib/actions/callback/index.js:226:23)
at async AuthInternal (webpack-internal:///(action-browser)/./node_modules/@auth/core/lib/index.js:66:24)
at async Auth (webpack-internal:///(action-browser)/./node_modules/@auth/core/index.js:126:34)
at async signIn (webpack-internal:///(action-browser)/./node_modules/next-auth/lib/actions.js:51:17)
at async $$ACTION_0 (webpack-internal:///(action-browser)/./actions/login.ts:46:9)
at async F:lng-v3node_modulesnextdistcompilednext-serverapp-page.runtime.dev.js:39:418
at async rw (F:lng-v3node_modulesnextdistcompilednext-serverapp-page.runtime.dev.js:38:7978)
at async r4 (F:lng-v3node_modulesnextdistcompilednext-serverapp-page.runtime.dev.js:41:1251)
at async doRender (F:lng-v3node_modulesnextdistserverbase-server.js:1438:30)
at async cacheEntry.responseCache.get.routeKind (F:lng-v3node_modulesnextdistserverbase-server.js:1599:28)
at async DevServer.renderToResponseWithComponentsImpl (F:lng-v3node_modulesnextdistserverbase-server.js:1507:28)
at async DevServer.renderPageComponent (F:lng-v3node_modulesnextdistserverbase-server.js:1931:24)
at async DevServer.renderToResponseImpl (F:lng-v3node_modulesnextdistserverbase-server.js:1969:32)
at async DevServer.pipeImpl (F:lng-v3node_modulesnextdistserverbase-server.js:920:25)
at async NextNodeServer.handleCatchallRenderRequest (F:lng-v3node_modulesnextdistservernext-server.js:272:17)
at async DevServer.handleRequestImpl (F:lng-v3node_modulesnextdistserverbase-server.js:816:17)
at async F:lng-v3node_modulesnextdistserverdevnext-dev-server.js:339:20
at async Span.traceAsyncFn (F:lng-v3node_modulesnextdisttracetrace.js:154:20)
at async DevServer.handleRequest (F:lng-v3node_modulesnextdistserverdevnext-dev-server.js:336:24)
at async invokeRender (F:lng-v3node_modulesnextdistserverlibrouter-server.js:174:21)
at async handleRequest (F:lng-v3node_modulesnextdistserverlibrouter-server.js:353:24)
at async requestHandlerImpl (F:lng-v3node_modulesnextdistserverlibrouter-server.js:377:13)
at async Server.requestListener (F:lng-v3node_modulesnextdistserverlibstart-server.js:141:13)
[auth][details]: {
"provider": "credentials"
}
If you need any more info just let me know 🙂
I truly do apologise if this is a simple stupid mistake but are incredibly grateful to anyone who can offer help!
Many thanks,
Louis
2
Answers
I have also this problem [auth][error] CallbackRouteError: Read more at https://errors.authjs.dev#callbackrouteerror
[auth][cause]: Error
at Module.callback (webpack-internal:///(action-browser)/./node_modules/next-auth/node_modules/@auth/core/lib/actions/callback/index.js:226:23)