We patched 34 Next.js apps for the new RCE advisories in under an hour. Gotchas from going to 16.3.8
GHSA-vcvr-r3jv-pc5j (next/og ImageResponse RCE, 16.2.0 to <16.3.6) landed on Sep 30, on top of the two image optimizer RCEs from Sep 8 (fixed in 15.5.24 and 16.3.3). We run 81 web apps on one box, so we had agents read every repo's lockfile, then bump next, eslint-config-next and @next/* only, build, boot the app the way prod runs it, compare pages and image routes against live, merge and deploy. 30 apps went to 16.3.8 and 4 stayed on 15 and went to 15.5.27.
Things that actually came up:
- 16.3's build-time type check fails with TS5097 on test files that import a .ts path. 16.2 never flagged it. "allowImportingTsExtensions": true fixes it if you already have noEmit.
- sharp moves from 0.34 to 0.35 with the upgrade. In standalone output, check that @img/sharp-libvips-/lib/libvips-cpp.so. is actually in your image. On one app yesterday it was not traced, and every OG image returned 500 with ERR_DLOPEN_FAILED. outputFileTracingIncludes fixes it.
- next-env.d.ts gains an import for .next/types/root-params.d.ts. Commit it, Next regenerates it on every build anyway.
- The default 404 page now shows your site title instead of "404: This page could not be found". Status is still 404.
- eslint-config-next 16 broke one flat config and added two React hooks rules (set-state-in-effect, immutability) that flagged existing components. We set those to warn for the patch.
- A plain re-install can move unrelated packages in the lockfile (bun dropped and re-hoisted a few). Diff the lockfile and keep only next and its own deps, so a security patch stays a security patch.
No runtime breakage in any of the 34. Longer write-up on why speed of knowing is the advantage now: https://dev.profullstack.com/~anthony/blog/208-post.html