Hi all,
I’m encountering a persistent runtime error when trying to generate PDFs using Puppeteer within a Next.js App Router project deployed on Vercel. The PDF generation works correctly in my local development environment but fails consistently on Vercel deployments.
Project Details:
- **Project Name: Vectorcv
- Framework: Next.js (App Router)
- Node.js Runtime: Node 22.x (as per deployment logs)
- **error from vercel
Error in PDF generation: Error: The input directory "/var/task/.next/server/bin" does not exist.
at d.executablePath (/var/task/.next/server/chunks/191.js:1:64134)
at l (/var/task/.next/server/app/api/pdf/route.js:1:1697)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async u (/var/task/.next/server/app/api/pdf/route.js:1:4235)
at async /var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:38411
at async e_.execute (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:27880)
at async e_.handle (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:39943)
at async en (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:25516)
at async ea.responseCache.get.routeKind (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:1028)
at async r9.renderToResponseWithComponentsImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:508)
Error in PDF API route: Error: Failed to generate PDF: The input directory "/var/task/.next/server/bin" does not exist.
at l (/var/task/.next/server/app/api/pdf/route.js:1:3486)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async u (/var/task/.next/server/app/api/pdf/route.js:1:4235)
at async /var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:38411
at async e_.execute (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:27880)
at async e_.handle (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:39943)
at async en (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:25516)
at async ea.responseCache.get.routeKind (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:1028)
at async r9.renderToResponseWithComponentsImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:508)
at async r9.renderPageComponent (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:5102)
Problem Description: The /api/pdf serverless function is designed to generate a PDF from HTML content using puppeteer-core and @sparticuz/chromium-min. While this works locally, on Vercel it fails with the following runtime error logged in the function logs:
Error: Failed to generate PDF: The input directory "/var/task/.next/server/bin" does not exist.
at d.executablePath (/var/task/.next/server/chunks/191.js:1:64134)
at l (/var/task/.next/server/app/api/pdf/route.js:1:1697)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async u (/var/task/.next/server/app/api/pdf/route.js:1:4235)
... (rest of stack trace) ...
This indicates that the necessary Chromium binary files provided by @sparticuz/chromium-min are not being found at the expected path within the Vercel runtime environment.
Troubleshooting Steps Taken:
- Dependencies: Confirmed use of
puppeteer-coreand@sparticuz/chromium-min(switched from the full@sparticuz/chromiumin an attempt to resolve). - Dynamic Imports: Implemented dynamic imports (
await import(...)) for bothpuppeteer-coreand@sparticuz/chromium-minwithin the service function (lib/services/pdf.service.ts) that handles PDF generation. This successfully reduced the reported Vercel function size from ~68MB to ~7MB, suggesting the initial bundle size limit is not the issue. next.config.mjsConfigurations: Tried various configurations, including:
- The recommended setup:
experimental: { serverComponentsExternalPackages: ['@sparticuz/chromium-min'], outputFileTracingIncludes: { '/api/pdf': ['./node_modules/@sparticuz/chromium-min/**'] } } - Using more specific paths in
outputFileTracingIncludes(e.g., targeting thebindirectory). - Removing
@sparticuz/chromium-minfromserverComponentsExternalPackages. - Removing
outputFileTracingIncludesentirely. - Using
@vercel/nft’swithFileTracinghelper. - Removing the entire
experimentalblock related to tracing/externals. None of these configuration changes resolved the runtime path error.
- Environment Variables: Added
SPARTICUZ_FUNCTION_NAME=pdf-generatorto Vercel environment variables based on troubleshooting guides. Confirmed other potentially conflicting variables likePUPPETEER_EXECUTABLE_PATHare not set. - Code Structure: The API route (
app/api/pdf/route.tsx) simply imports and calls a service function (lib/services/pdf.service.ts). The service function contains the dynamic imports and Puppeteer logic, correctly callingawait chromium.executablePath().
Despite these steps, the runtime error persists across deployments. It seems like an issue with Vercel’s build process not correctly tracing or packaging the necessary binary files from @sparticuz/chromium-min into the expected runtime location (/var/task/.next/server/bin or similar path resolved by chromium.executablePath()).
Could you please provide guidance on how to resolve this file tracing/packaging issue for @sparticuz/chromium-min within the Vercel environment?
also having @sparticuz/chromium-min has helped me keep this under 50MB limit
any assistance will be greatly appreciated. thank you.