Keel / Audit / #3
⚠️ PARTIAL

fix(instrumentation): await instrumentation in RouteModule.prepare

Repo vercel/next.js PR #94306 Coverage 92% Verified Sun, 07 Jun 2026 15:43:49 GMT

Shareable link

https://keel-5.polsia.app/v/3

Intent source

Acceptance criteria

3/4 criteria met · 92% coverage

Verdict Criterion Evidence
✅ PASS Deploy to Vercel, then hit `/api/check` on a cold lambda with a few concurrent requests The diff adds a new test case 'with-async-node-app-route' with `skipDeployment: false`, meaning it runs on Vercel deployments. The test hits `/api/check` endpoint which is created in the new fixture files.
⚠️ PARTIAL `instrumentation.ts#register()` sets `globalThis.__registerStarted`, awaits 200ms (to stand in for the top-level `await import(...)` chain that real OTel / app-bootstrap hooks do), then sets `globalThis.__registerFinished`. The route reports both timestamps. On a cold lambda, responses come back with `"registerFinished": null` and `"registerFinishedBeforeRequest": false` — the handler ran while `register()` was still awaiting. The test fixture uses a similar pattern: `instrumentation.node.js` awaits 1000ms sleep then sets `globalThis.instrumentationFinished = true`. However, it only checks `finished: Boolean((globalThis as any).instrumentationFinished)` rather than tracking timestamps like `registerStarted`/`registerFinished`/`registerFinishedBeforeRequest`. The spirit of the criterion is met but not the exact implementation described.
✅ PASS Just add the missing `await`: `await ensureInstrumentationRegistered(absoluteProjectDir, this.distDir)` The diff in `route-module.ts` clearly adds the missing `await` before `ensureInstrumentationRegistered(absoluteProjectDir, this.distDir)`, exactly as specified in the suggested fix.
✅ PASS The function memoizes a single promise per process, so the await is a microtask no-op on every request after the first. The cold-start request would block until `register()` is actually done, which is the behavior the docs describe. The fix adds `await` to `ensureInstrumentationRegistered` which is already memoized. The test validates the behavior by checking `finished: true` is returned, confirming the handler waits for instrumentation to complete. The comment in the diff also explains this rationale.

Summary

The PR correctly implements the core fix by adding the missing `await` before `ensureInstrumentationRegistered` in `route-module.ts`. It also adds an end-to-end test that runs on Vercel deployments (`skipDeployment: false`) with a fixture that simulates async instrumentation via a 1-second sleep. The test fixture uses a slightly simplified verification approach (boolean flag vs timestamps) compared to the reproduction described in the spec, but the functional intent is fully covered.