I have a Next.js 15.2.3 server api route that takes in a monitorId
and gives back a result in the database.
The Next.js 15.2.3 server api route path is
app/(private)/monitors/[monitorId]/api-get-monitor/route.ts
.
// app/(private)/monitors/[monitorId]/api-get-monitor/route.ts
import { NextRequest, NextResponse } from "next/server";
import { sql } from "@/app/lib/db";
import { loginIsRequiredServer } from "@/app/lib/loginIsRequiredServer";
import { getServerSession } from "next-auth";
import { authConfig } from "@/app/lib/auth";
// Use the built-in RequestContext type
export async function GET(request: NextRequest, context: { params?: { monitorId?: string } }) {
// Ensure params exist
if (!context.params?.monitorId) {
return NextResponse.json({ message: "Missing monitor ID" }, { status: 400 });
}
const { monitorId } = context.params;
console.error(`api-get-monitor · Get Monitor: ${monitorId}`);
// Session check
await loginIsRequiredServer();
const session = await getServerSession(authConfig);
if (!session) {
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
try {
// Query the database for monitor details using the monitorId
const res = await sql(
`SELECT monitor_id, title, what_to_monitor, url_to_monitor, escalation_email_on,
escalation_email_to, check_frequency, last_checked_timestamp, is_offline, offline_datetime
FROM u_monitors_index WHERE monitor_id = $1`,
[monitorId]
);
if (res.rows.length === 0) {
return NextResponse.json({ message: "Monitor not found" }, { status: 404 });
}
return NextResponse.json({ data: res.rows[0] });
} catch (error) {
console.error("get-monitor · Error getting:", error);
return NextResponse.json({ message: "Error getting monitor" }, { status: 500 });
}
}
This works locally but when I deploy it to Google Cloud Run I get the following error
Linting and checking validity of types ...
Failed to compile.
app/(private)/monitors/[monitorId]/api-get-monitor/route.ts
Type error: Route "app/(private)/monitors/[monitorId]/api-get-monitor/route.ts" has an invalid "GET" export:
Type "{ params?: { monitorId?: string | undefined; } | undefined; }" is not a valid type for the function's second argument.
Expected "Promise<any>", got "{ monitorId?: string | undefined; } | undefined".
Expected "Promise<any>", got "undefined".
Next.js build worker exited with code: 1 and signal: null
Is not params
is just an object passed by Next.js, not an async operation? I do not understand the error here.
You're getting that error during your production build because from NextJS 15, params is now a promise and not a synchronous object as they were in the versions preceding NextJS 15. All you have to do is adjust your type for your params to be a promise object.
export async function GET(request: NextRequest, context: { params: Promise<{ monitorId: string }> }) {
const monitorId = (await context.params).monitorId;
// Ensure params exist
if (!monitorId) {
return NextResponse.json({ message: "Missing monitor ID" }, { status: 400 });
}
console.error(`api-get-monitor · Get Monitor: ${monitorId}`);
// Session check
await loginIsRequiredServer();
const session = await getServerSession(authConfig);
if (!session) {
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
try {
// Query the database for monitor details using the monitorId
const res = await sql(
`SELECT monitor_id, title, what_to_monitor, url_to_monitor, escalation_email_on,
escalation_email_to, check_frequency, last_checked_timestamp, is_offline, offline_datetime
FROM u_monitors_index WHERE monitor_id = $1`,
[monitorId]
);
if (res.rows.length === 0) {
return NextResponse.json({ message: "Monitor not found" }, { status: 404 });
}
return NextResponse.json({ data: res.rows[0] });
} catch (error) {
console.error("get-monitor · Error getting:", error);
return NextResponse.json({ message: "Error getting monitor" }, { status: 500 });
}
}
Here is a reference to the docs: https://nextjs.org/docs/app/api-reference/file-conventions/route#context-optional