Invalid Type Error for Route Handler's Second Argument in Next.js 15
Route handlers in Next.js 15 are throwing a TypeScript error for the second argument's type, even when using the documented pattern.
Repository: https://github.com/shellen/repro-next-route-handler
Steps to reproduce:
- Create a new Next.js 15 project with TypeScript
- Add a route handler with PATCH method
- Run
npm run build
Build fails with error:
src/app/api/test/[id]/route.ts
Type error: Route "src/app/api/test/[id]/route.ts" has an invalid "PATCH" export:
Type "{ params: { id: string; }; }" is not a valid type for the function's second argument.
npx create-next-app@latest repro-next-route-handler
- TypeScript: Yes
- ESLint: Yes
- Tailwind: No
- src/ directory: Yes
- App Router: Yes
- Custom import alias: No
cd repro-next-route-handler
Make sure to set React versions to:
"react": "18.2.0",
"react-dom": "18.2.0",
npm run build
Here are things I've tried to fix it.
Approach | Description | Result | Note |
---|---|---|---|
Custom Props Type | Used Props interface for params | Failed | Type error |
Props Interface | Added interface for parameters | Failed | Type error |
Next.js Types | Used NextRequest and return types | Failed | Same type error persisted |
Base Request Type | Used standard Request type | Failed | Type error remained |
Record Type | Used Record<string, string | string[]> | Failed | No improvement |
Remove Dependencies | Removed @hello-pangea/dnd | Failed | Not dependency related |
Disable TypedRoutes | Removed from next.config | Failed | Not config related |
RouteSegment Type | Created custom RouteSegment type | Failed | Type error persisted |
Runtime Specification | Added nodejs runtime | Failed | No effect on type error |
Middleware Approach | Added type validation | Failed | Same issue |
RouteContext Type | Custom context interface | Failed | Invalid second argument |
NodeJS Runtime + NextRequest | Combined runtime with NextRequest | Failed | Same type error |
Handler Function Pattern | Separated business logic | Failed | ESLint any error |
Type Assertion Pattern | Used 'as unknown as' | Failed | Type error remained |
Custom Route Context | Created RouteContext type | Failed | Not accepted by Next.js |
This table shows systematic attempts to resolve the issue through various typing approaches and configurations, all resulting in the same core type error with the route handler's second argument.
Running React 18 or React 19 does not seem to affect it. We're using a dependency that still needs React 18 but as mentioned, rolling the react version forward didn't seem to fix either.
This is a Next.js project bootstrapped with create-next-app
.
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx
. The page auto-updates as you edit the file.
This project uses next/font
to automatically optimize and load Geist, a new font family for Vercel.
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
- Removed the second argument from route handler function.
- Extracted the dynamic route parameter id from the request URL.You can use the
request.nextUrl
property to access the URL and extract parameters.
Updated route.ts file:
// src/app/api/test/[id]/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function PATCH(request: NextRequest) {
// Extract the 'id' from the request URL
const { pathname } = request.nextUrl;
const segments = pathname.split('/');
const id = segments[segments.length - 1]; // Assuming 'id' is the last segment
return NextResponse.json({ id });
}