Next.js 15+ exposes an instrumentation hook that intercepts unhandled server-side errors before the framework returns a generic error response. By exporting an onRequestError function from your instrumentation.js (or .ts) file, you can forward these errors to Atatus with full request and routing context.
Why This Is Required
Next.js catches errors thrown during Server Component rendering, Route Handlers, and Server Actions internally, and serves a generic error page. Because the framework handles these errors before they propagate, the Atatus agent cannot capture them through standard auto-instrumentation alone. The onRequestError hook provides a global entry point to intercept and report these errors.
Setup
Create an instrumentation.js (or instrumentation.ts) file in your project root (or inside src/ if your project uses the src layout).
instrumentation.js file, add the onRequestError export to it alongside your existing code.
JavaScript
/** @type {import('next').Instrumentation['onRequestError']} */
export async function onRequestError(err, request, context) {
if (process.env.NEXT_RUNTIME !== "nodejs") {
return;
}
const atatus = require("atatus-nodejs");
atatus.notifyError(
err instanceof Error ? err : new Error(String(err)),
{
handled: false,
customData: {
source: "next-on-request-error",
request,
context,
digest:
err &&
typeof err === "object" &&
"digest" in err
? String(err.digest)
: undefined,
},
}
);
}
TypeScript
import type { Instrumentation } from "next";
type AtatusAgent = typeof import("atatus-nodejs");
function getDigest(err: unknown) {
if (typeof err === "object" && err !== null && "digest" in err) {
return String(err.digest);
}
return undefined;
}
function normalizeError(err: unknown) {
return err instanceof Error ? err : new Error(String(err));
}
export const onRequestError: Instrumentation.onRequestError = async (
err,
request,
context
) => {
if (process.env.NEXT_RUNTIME !== "nodejs") {
return;
}
const atatus = require("atatus-nodejs") as AtatusAgent;
atatus.notifyError(normalizeError(err), {
handled: false,
customData: {
source: "next-on-request-error",
request,
context,
digest: getDigest(err),
},
});
};
How It Works
When an unhandled error occurs during server-side rendering or routing, Next.js invokes onRequestError. The function:
- Guards against non-Node.js runtimes (Edge Runtime is not supported).
- Dynamically requires
atatus-nodejsto avoid bundler conflicts. - Reports the error via
atatus.notifyErrorwith request metadata and the Next.js error digest.
Reported errors appear under Exceptions in your Atatus dashboard with full stack traces.
onRequestError hook runs only on the server. For client-side error tracking, use the Atatus Browser agent.
Troubleshooting
If unhandled server-side errors are not appearing after setup:
- Incorrect file location: Place
instrumentation.js/instrumentation.tsin the project root or insidesrc/(adjacent toapporpages). It must not be placed insideapp/orpages/. - Missing export: The function must be exported —
export async function onRequestError. - Server not restarted: Next.js compiles the instrumentation file at startup. You must restart the dev or production server after any changes.
- Next.js 14 — experimental flag required: Enable the instrumentation hook explicitly in
next.config.js:javascript const nextConfig = { experimental: { instrumentationHook: true, }, };
Exclude Packages from Bundling
Next.js bundles server-side dependencies by default. The Atatus agent instruments packages by intercepting Node.js require() calls at runtime — this only works when packages are loaded natively, not compiled into the bundle.
Add atatus-nodejs and any database drivers you use to serverExternalPackages in next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
serverExternalPackages: ["atatus-nodejs", "mongodb", "pg", "redis", "mysql2", "mongoose"],
};
module.exports = nextConfig;
Include only the packages your project actually uses. This ensures they are resolved via Node.js require() at runtime, enabling the Atatus agent to instrument database queries, external HTTP calls, and other operations.
+1-415-800-4104