I'm implementing authentication middleware in a Next.js (v13+) application using NextAuth.js, and I'm encountering an error when trying to validate the session token. The error occurs in the oidc-token-hash dependency, but I can't identify what's causing it.
Error Details
TypeError: Cannot read properties of undefined (reading 'substring')
at [project]/node_modules/oidc-token-hash/lib/shake256.js [middleware-edge]
...
Current Implementation
Here's my middleware code (simplified for clarity):
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";
import type { UserRole } from "@prisma/client";
import { refreshSession } from "@/lib/auth/session";
import { validateCsrfToken } from "@/lib/auth/csrf";
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
if (shouldSkipMiddleware(pathname)) {
return NextResponse.next();
}
// Debugging: Log request details
console.log(`Processing ${request.method} ${pathname}`);
let token;
try {
token = await getToken({
req: request,
secret: process.env.NEXTAUTH_SECRET,
});
console.log("Token:", token ? "Exists" : "Null");
if (token) {
console.log("Token details:", {
sub: token.sub,
role: token.role,
exp: token.exp,
status: token.status,
});
}
} catch (error) {
console.error("Token validation error:", error);
return redirectToLogin(request, pathname, "TokenError");
}
if (!token) {
console.log("No token - redirecting to login");
return redirectToLogin(request, pathname, "NoSession");
}
if (!token.sub) {
console.log("Token missing sub - redirecting to login");
return redirectToLogin(request, pathname, "InvalidSession");
}
// Handle authenticated users trying to access auth routes
if (authRoutes.has(pathname)) {
return redirectToRoleDashboard(token.role as UserRole, request);
}
// Check for session expiration
if (typeof token.exp === "number" && isSessionExpired(token.exp)) {
return redirectToLogin(request, pathname, "SessionExpired");
}
// Try refreshing session
try {
await refreshSession(token.id);
} catch (error) {
console.error("Session validation failed:", error);
return redirectToLogin(request, pathname, "SessionError");
}
// Unverified account
if (token.status !== "VERIFIED") {
return redirectToVerification(request, pathname);
}
// Password reset required
if (token.resetRequired && pathname !== "/auth/reset-password") {
return redirectToPasswordReset(request, pathname);
}
// CSRF check for sensitive POSTs
if (request.method === "POST" && sensitiveRoutes.has(pathname)) {
const csrfValid = await validateCsrfToken(request);
if (!csrfValid) {
return new NextResponse("Invalid CSRF token", { status: 403 });
}
}
// Role-based routing
return handleRoleBasedRouting(token.role as UserRole, pathname, request);
}
Full Error Stack
TypeError: Cannot read properties of undefined (reading 'substring')
at [project]/node_modules/oidc-token-hash/lib/shake256.js [middleware-edge] (ecmascript) (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/node_modules_0dd80849._.js:1699:40)
at <unknown> (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:709:27)
at runModuleExecutionHooks (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:755:9)
at instantiateModule (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:707:9)
at getOrInstantiateModuleFromParent (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:640:12)
at commonJsRequire (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:158:20)
at [project]/node_modules/oidc-token-hash/lib/index.js [middleware-edge] (ecmascript) (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/node_modules_0dd80849._.js:1712:40)
at <unknown> (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:709:27)
at runModuleExecutionHooks (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:755:9)
at instantiateModule (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:707:9)
What I've Tried
- Verified
NEXTAUTH_SECRETis properly set in environment variables - Added extensive error logging and try-catch blocks
- Confirmed the session cookie exists in the request
- Updated all dependencies (
next-auth,next, etc.)
Additional Information
- Next.js version: 15.2.4
- NextAuth.js version: 4.24.11
- Authentication Provider: Credentials provider with Prisma adapter
- Session Strategy: JWT
- Reproduction: The error occurs when accessing all routes
Questions
- What could be causing the
substringerror inoidc-token-hash? - Is there a configuration issue with how I'm using
getTokenin middleware? - Could this be related to JWT vs. database session strategy?
- Are there known compatibility issues between these package versions?