fix: handle missing videos directory in getVideoSlugs (auto)#18015
Draft
pettinarip wants to merge 1 commit intodevfrom
Draft
fix: handle missing videos directory in getVideoSlugs (auto)#18015pettinarip wants to merge 1 commit intodevfrom
pettinarip wants to merge 1 commit intodevfrom
Conversation
Resolves grafana-logs item grafana-fn-error-enoent-no-such-file-or-directory-scandir-x-at-async-o-next-se. The sitemap.xml route calls getVideoSlugs(), which does a readdir on public/content/videos. Netlify Functions don't bundle public/ content, so the call throws ENOENT at runtime (100 hits in Grafana logs). getPostSlugs already mirrors this degradation pattern for the same root cause; getVideoSlugs now matches by catching ENOENT and returning an empty slug list.
✅ Deploy Preview for ethereumorg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
wackerow
approved these changes
Apr 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
app/sitemap.tsthrows ENOENT at runtime on Netlify becausegetVideoSlugs()does a rawreaddironpublic/content/videos, and that directory isn't bundled into serverless functions.getPostSlugsalready guards the same failure mode insrc/lib/utils/md.ts; this PR applies the same ENOENT handling togetVideoSlugsso the sitemap degrades gracefully instead of 500ing.pnpm build), all video slugs are still returned.Error Context
/sitemap.xml(Netlify Function.next/server/app/sitemap.xml/route.js)Changes
src/lib/utils/videos.ts: wrap thereaddir(videosDir, ...)call ingetVideoSlugs()with a try/catch that maps ENOENT to an empty slug list (with aconsole.warn), mirroring the graceful fallback already implemented ingetPostSlugs(src/lib/utils/md.ts:64-74).Analysis
Stack trace points at
/var/task/.next/server/app/sitemap.xml/route.jsand a scandir on/var/task/public/content/videos. That's the Netlify Functions sandbox path —public/content/*is only bundled into functions when explicitly listed innetlify.toml'sincluded_files, which today listsi18n.config.json,src/intl/**/*, andsrc/data-layer/mocks/**/*, but notpublic/content/videos.app/sitemap.tswas updated on 2026-04-13 (videos-refactor PR #17870 reapply) to callgetVideoSlugs()so the sitemap picks up/videos/<slug>/URLs. The individual video pages are statically generated at build time (app/[locale]/videos/[slug]/page.tsxusesgenerateStaticParams), so they don't hit this path — butapp/sitemap.tsdoes.getPostSlugsinsrc/lib/utils/md.tshandles this same environmental mismatch by catching ENOENT and returning[]with a warning.getVideoSlugsdidn't — so any time Netlify invokes the sitemap route at runtime (regardless of why), we throw. 100 hits in the Grafana logs confirms it's firing consistently.Matching the existing pattern keeps the fix small and consistent with the codebase's accepted trade-off: at build time we emit a complete sitemap with video URLs; if the sitemap route is re-executed at runtime without the content bundle, we still return a valid (video-less) sitemap instead of 500ing.
Related issue: #18014 tracks the broader WARN-level variant of this same root cause from
getPostSlugs.Test Plan
/sitemap.xmlon the preview — expect 200, with/videos/<slug>/entries present (built once at build time).dev.export const dynamic = 'force-static'in a follow-up so runtime re-invocation never drops video URLs; out of scope here.Opened automatically by the Recovery Agent.