chore(deps): delete the inert next@16.3.1 patch and correct the comments about it (#4086)

Next 16.3.1 is the first release containing upstream's SVG-loader fix (vercel/next.js#96681) — it ships 'VipsForeignLoadSvg' in the sharp.unblock list itself, in both the CJS and ESM image-optimizer copies. Our local patch was therefore inert: the installed files are byte-identical (sha256) to the published tarball, and the patch does not even apply (its hunk context wants Png immediately followed by Tiff; 16.3.1 has Svg between them).

It looked healthy because pnpm silently no-ops an already-applied patch — install exits 0, prints no warning, and still creates a patch_hash= virtual-store directory.

Deletes the patch and its patchedDependencies entry (@mantine/hooks untouched), regenerates the lockfile, and corrects three comments that asserted upstream still lacked the entry.

The CI guard stays: it asserts the outcome (the installed Next unblocks the SVG loader), so it keeps protecting against a future Next regressing this the way 16.3.0 did. Verified post-removal: guard green, still goes red when the loader entry is stripped from both installed copies, and /api/og renders PNGs on both paths on the preview build.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Zachary Lowden
2026-08-19 12:20:51 -05:00
committed by GitHub
parent 800c1756c7
commit f419a64461
5 changed files with 75 additions and 64 deletions
+1 -2
View File
@@ -434,8 +434,7 @@
"utf-8-validate"
],
"patchedDependencies": {
"@mantine/hooks": "patches/@mantine__hooks.patch",
"next@16.3.1": "patches/next@16.3.1.patch"
"@mantine/hooks": "patches/@mantine__hooks.patch"
}
}
}
-24
View File
@@ -1,24 +0,0 @@
diff --git a/dist/esm/server/image-optimizer.js b/dist/esm/server/image-optimizer.js
index 09277f1df5ed73d006e1769b405f148cab406dff..50135855db356fa22ab03b050ce24a4182c60a8d 100644
--- a/dist/esm/server/image-optimizer.js
+++ b/dist/esm/server/image-optimizer.js
@@ -90,6 +90,7 @@ export function getSharp(concurrency, operationCache) {
'VipsForeignLoadJpeg',
'VipsForeignLoadNsgif',
'VipsForeignLoadPng',
+ 'VipsForeignLoadSvg',
'VipsForeignLoadTiff',
'VipsForeignLoadWebp'
]
diff --git a/dist/server/image-optimizer.js b/dist/server/image-optimizer.js
index 9be0c9ae912f3824e9253641eee3273f17080a69..31b5c6e3e46f40a994f62c4d43df6a8bbf971869 100644
--- a/dist/server/image-optimizer.js
+++ b/dist/server/image-optimizer.js
@@ -210,6 +210,7 @@ function getSharp(concurrency, operationCache) {
'VipsForeignLoadJpeg',
'VipsForeignLoadNsgif',
'VipsForeignLoadPng',
+ 'VipsForeignLoadSvg',
'VipsForeignLoadTiff',
'VipsForeignLoadWebp'
]
+14 -17
View File
@@ -20,9 +20,6 @@ patchedDependencies:
'@mantine/hooks':
hash: b45a85bd4d007c796b93eb90a75d3234b81cce13964921b25721734c7ed79f64
path: patches/@mantine__hooks.patch
next@16.3.1:
hash: d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6
path: patches/next@16.3.1.patch
importers:
@@ -66,7 +63,7 @@ importers:
version: link:packages/civitai-flipt
'@civitai/next-axiom':
specifier: ^0.17.0
version: 0.17.0(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))
version: 0.17.0(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))
'@civitai/shared':
specifier: workspace:*
version: link:packages/civitai-shared
@@ -156,7 +153,7 @@ importers:
version: 16.3.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
'@next/third-parties':
specifier: ^15.0.3
version: 15.4.6(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
version: 15.4.6(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
'@node-oauth/oauth2-server':
specifier: ^5.3.0
version: 5.3.0
@@ -312,7 +309,7 @@ importers:
version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2)
'@trpc/next':
specifier: ^11.17.0
version: 11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)
version: 11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)
'@trpc/react-query':
specifier: ^11.17.0
version: 11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2)
@@ -483,7 +480,7 @@ importers:
version: 1.11.5
next:
specifier: ^16.3.1
version: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
version: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
nodemailer:
specifier: ^6.8.0
version: 6.10.1
@@ -543,7 +540,7 @@ importers:
version: 7.12.0(algoliasearch@4.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-instantsearch-router-nextjs:
specifier: 7.12.0
version: 7.12.0(algoliasearch@4.25.2)(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
version: 7.12.0(algoliasearch@4.25.2)(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
react-intersection-observer:
specifier: ^9.4.0
version: 9.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -13199,9 +13196,9 @@ snapshots:
dependencies:
fast-xml-parser: 5.10.1
'@civitai/next-axiom@0.17.0(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))':
'@civitai/next-axiom@0.17.0(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))':
dependencies:
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
whatwg-fetch: 3.6.20
'@clavata/sdk@0.2.3':
@@ -14423,9 +14420,9 @@ snapshots:
'@next/swc-win32-x64-msvc@16.3.1':
optional: true
'@next/third-parties@15.4.6(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)':
'@next/third-parties@15.4.6(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)':
dependencies:
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
react: 18.3.1
third-party-capital: 1.0.20
@@ -16623,11 +16620,11 @@ snapshots:
'@trpc/server': 11.17.0(typescript@5.9.2)
typescript: 5.9.2
'@trpc/next@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)':
'@trpc/next@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)':
dependencies:
'@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2)
'@trpc/server': 11.17.0(typescript@5.9.2)
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
typescript: 5.9.2
@@ -21926,7 +21923,7 @@ snapshots:
neo-async@2.6.2: {}
next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0):
next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0):
dependencies:
'@next/env': 16.3.1
'@swc/helpers': 0.5.23
@@ -23104,10 +23101,10 @@ snapshots:
react: 18.3.1
use-sync-external-store: 1.5.0(react@18.3.1)
react-instantsearch-router-nextjs@7.12.0(algoliasearch@4.25.2)(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1):
react-instantsearch-router-nextjs@7.12.0(algoliasearch@4.25.2)(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1):
dependencies:
instantsearch.js: 4.73.0(algoliasearch@4.25.2)
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
react-instantsearch-core: 7.12.0(algoliasearch@4.25.2)(react@18.3.1)
transitivePeerDependencies:
- algoliasearch
+33 -18
View File
@@ -12,22 +12,32 @@
* WHAT IT ASSERTS, AND WHY THAT IS THE RIGHT INVARIANT. Next 16.3.0 applies a process-global
* libvips block on first image-optimizer use and re-enables only six RASTER loaders; SVG is
* not among them, so every `ImageResponse` in the process throws
* `Input buffer contains unsupported image format` from then on. We carry upstream
* vercel/next.js#96681 as `patches/next@16.3.1.patch` until we are on a Next that contains it.
* `Input buffer contains unsupported image format` from then on. Upstream fixed that in
* vercel/next.js#96681, and 16.3.1 is the first release that CONTAINS the fix: it ships
* `'VipsForeignLoadSvg'` in the unblock list itself. We carried the one-line fix as a pnpm
* patch only while we were on 16.3.0; there is no Next patch now, and this guard needs none.
*
* The assertion is deliberately "the installed Next unblocks SVG", NOT "our patch file is on
* disk" and NOT "we are on any particular version":
* So what this protects against today is a FUTURE Next regressing the loader entry again —
* which is exactly why the assertion is deliberately "the installed Next unblocks SVG", NOT
* "our patch file is on disk" and NOT "we are on any particular version":
*
* - reading `node_modules` rather than `patches/` is the whole point — a patch that exists
* but did not APPLY (unregistered key, failed hunk, a stale lockfile hash) is exactly the
* silent failure this catches, and a patch-file grep would sail through it;
* - staying version-agnostic means the guard does not have to be retired in the same commit
* that bumps Next. If a future Next ships the loader entry itself, this still passes with
* the patch retired; the patch is separately version-pinned through
* `pnpm.patchedDependencies`, so a bump fails the install rather than silently carrying a
* stale patch. (Measured on the 16.3.0 -> 16.3.1 bump: the patch still applies, and the
* installed 16.3.1 carries exactly ONE occurrence of the loader entry per copy — i.e. the
* patch is what puts it there, upstream still does not.)
* - reading `node_modules` rather than `patches/` is the whole point. It is the only form
* that is correct both now (upstream supplies the entry, no patch exists) and in the
* patched past (a patch that exists but did not APPLY — unregistered key, failed hunk, a
* stale lockfile hash — is exactly the silent failure this catches, and a patch-file grep
* would sail through it);
* - staying version-agnostic means the guard does not have to be retired, re-pinned or
* re-dated in the same commit that bumps Next. It keeps passing on any Next that unblocks
* the loader, and goes red the moment one does not — whoever hits that decides between
* re-introducing a patch and pinning back.
*
* 🔴 One occurrence per copy is NOT evidence about WHO supplied it. The count is the same
* whether upstream ships the entry or a patch inserted it, so it cannot distinguish the two —
* reading it as proof of a working patch is how the now-deleted 16.3.1 patch was carried for
* a while after it had gone inert (pnpm silently no-ops an already-applied patch: rc=0, no
* warning, and it still creates a `patch_hash=…` virtual-store dir, so it LOOKS applied).
* To attribute the entry, compare the installed file against the pristine published tarball —
* on 16.3.1 they are byte-identical, so upstream is the source.
*
* BOTH BUILDS, SKIPPING WHAT IS ABSENT. Next ships this module twice — `dist/server/` (CJS)
* and `dist/esm/server/`. A full `pnpm install` has both; the production standalone image has
@@ -115,10 +125,15 @@ function formatReport(report) {
const FAILURE_EXPLANATION =
`FAIL: the installed Next does not unblock the libvips SVG loader (${REQUIRED_LOADER}).\n` +
'Every `next/og` ImageResponse — i.e. all of /api/og — will return 500 as soon as anything\n' +
'touches the image optimizer in that process. Check that `patches/next@<version>.patch` is\n' +
'still registered under `pnpm.patchedDependencies` in package.json and that\n' +
'`pnpm install` applied it; this reads node_modules, so a patch file that exists but did\n' +
'not apply fails here. See src/tests/api/og.image-optimizer-sharp.test.ts for the outage.';
'touches the image optimizer in that process.\n' +
'Next >= 16.3.1 ships this loader entry itself (vercel/next.js#96681), and we carry no Next\n' +
'patch, so this failing means the Next you installed has REGRESSED it — or dependencies are\n' +
'stale. Re-run `pnpm install` and re-check; if the installed Next genuinely lacks the entry,\n' +
'pin Next back to a release that unblocks the loader, or re-introduce a pnpm patch adding\n' +
`'${REQUIRED_LOADER}' to the sharp.unblock({ operation: [...] }) list in BOTH\n` +
'dist/server/image-optimizer.js and dist/esm/server/image-optimizer.js. This reads\n' +
'node_modules, not patches/, so it judges the artifact you actually installed however the\n' +
'entry got there. See src/tests/api/og.image-optimizer-sharp.test.ts for the outage.';
const NO_COPIES_EXPLANATION =
'FAIL: found no copy of next/dist/**/server/image-optimizer.js to read, so this check ' +
+27 -3
View File
@@ -22,9 +22,17 @@ import type { NextApiRequest, NextApiResponse } from 'next';
* `Input buffer contains unsupported image format` — and `/api/og` returns 500
* for the rest of that pod's life. Upstream: vercel/next.js#96301 introduced it,
* vercel/next.js#96681 fixes it by adding `'VipsForeignLoadSvg'` to the unblock
* list. We carry that one-line fix as `patches/next@16.3.1.patch` until we are on
* a Next release that contains it — 16.3.1 still does not, so the bump to it
* renamed the patch and kept it.
* list. We carried that one-line fix as a pnpm patch while we were on 16.3.0.
* 16.3.1 is the first release that CONTAINS the fix — it ships the loader entry
* upstream — so the patch became inert on that bump and has been deleted. What
* these cases guard now is a FUTURE Next regressing the entry again.
*
* 🔴 Note for whoever reads this next: "the installed file has one occurrence of
* `'VipsForeignLoadSvg'`" does NOT tell you whether upstream or a patch put it
* there — the count is identical either way. That ambiguity is how the inert
* patch survived a bump (pnpm no-ops an already-applied patch with rc=0 and no
* warning). Attribute it by diffing the installed file against the published
* tarball; on 16.3.1 they are byte-identical.
*
* WHY THIS TEST IS SHAPED THE WAY IT IS. 🔴 The ordering is the whole test.
* Rendering an `ImageResponse` in a fresh process SUCCEEDS even on a broken
@@ -66,6 +74,22 @@ import type { NextApiRequest, NextApiResponse } from 'next';
* reports 1 copy read and the ESM copy as skipped.
* - both copies absent: exits 1 rather than passing vacuously on zero reads.
*
* Re-watched 2026-08-18 on stock 16.3.1 with the patch DELETED — the mutations
* above that reinstall or delete a patch no longer reproduce, since there is no
* Next patch to remove, so the guard was driven against node_modules directly:
* - installed copies byte-identical (sha256) to the published next-16.3.1
* tarball, and the guard exits 0 reporting `copies read: 2`, both ok. The
* hash equality is the part that attributes the loader entry to upstream;
* the guard's own green cannot, since it counts rather than attributes.
* - `'VipsForeignLoadSvg',` stripped from BOTH installed copies, leaving the
* `unblock({ operation: [...] })` call structurally intact so the SVG branch
* is reached rather than the no-unblock-call fallback: exits 1 reporting
* both copies "does NOT unblock VipsForeignLoadSvg", `copies read: 2`.
* Restored from a `cp -a` backup (never `git checkout` — node_modules is
* untracked) and re-confirmed green.
* - both copies moved aside: exits 1 with "this check proved nothing",
* `copies read: 0` — still no vacuous pass.
*
* SCOPE / WHAT THIS DOES NOT COVER. This runs in-process, so it does not cover
* packaging failures under `output: 'standalone'` (the OTHER way `/api/og` has
* broken — see the `outputFileTracingIncludes['/api/og']` entry in