Problem
scripts/fetch-github-images.js writes images.json directly to its final path without using an atomic write pattern. If the CI job is cancelled, OOM-killed, or the process crashes mid-write, images.json is left truncated or containing partial JSON.
On the next build, ImagesCatalog.tsx fetches this file at runtime. A parse error causes the images page to render empty with no user-visible error message.
fetch-github-sbom.js already uses the correct pattern: write to a temp path, then fs.renameSync(tmp, dest). This ensures the destination is either the previous complete file or the new complete file — never a partial write.
Fix
In scripts/fetch-github-images.js, find the fs.writeFileSync(OUTPUT_FILE, ...) call and replace with:
const tmpFile = `${OUTPUT_FILE}.tmp`;
fs.writeFileSync(tmpFile, JSON.stringify(output, null, 2));
fs.renameSync(tmpFile, OUTPUT_FILE);
Reference
fetch-github-sbom.js uses this pattern already — search for .tmp in that file.
Problem
scripts/fetch-github-images.jswritesimages.jsondirectly to its final path without using an atomic write pattern. If the CI job is cancelled, OOM-killed, or the process crashes mid-write,images.jsonis left truncated or containing partial JSON.On the next build,
ImagesCatalog.tsxfetches this file at runtime. A parse error causes the images page to render empty with no user-visible error message.fetch-github-sbom.jsalready uses the correct pattern: write to a temp path, thenfs.renameSync(tmp, dest). This ensures the destination is either the previous complete file or the new complete file — never a partial write.Fix
In
scripts/fetch-github-images.js, find thefs.writeFileSync(OUTPUT_FILE, ...)call and replace with:Reference
fetch-github-sbom.jsuses this pattern already — search for.tmpin that file.