next.js: Route handler returns 404 instead of 200

Link to the code that reproduces this issue

https://github.com/moroshko/nextjs-pdfmake-issue

To Reproduce

  1. git clone https://github.com/moroshko/nextjs-pdfmake-issue.git
  2. cd nextjs-pdfmake-issue
  3. bun i
  4. bun dev
  5. Visit http://localhost:3000/api/hello

Current vs. Expected behavior

Expected: 200 Actual: 404

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 22.6.0: Fri Sep 15 13:39:52 PDT 2023; root:xnu-8796.141.3.700.8~1/RELEASE_X86_64
Binaries:
  Node: 18.17.0
  npm: 9.6.7
  Yarn: 1.22.19
  pnpm: N/A
Relevant Packages:
  next: 14.0.3-canary.8
  eslint-config-next: 14.0.3-canary.8
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.2.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router, Middleware / Edge (API routes, runtime)

Additional context

The following route handler returns a 404 when navigating to http://localhost:3000/api/hello:

app/api/hello/route.ts

import PdfPrinter from "pdfmake";

export async function GET() {
  try {
    const printer = new PdfPrinter({});

    return Response.json({ message: "ok" });
  } catch (error) {
    return Response.json({ error: "something went" });
  }
}

Commenting out const printer = new PdfPrinter({}); solves the issue (200 is returned, as expected).

Here is the 404 response body:

<!DOCTYPE html>
<html id="__next_error__">
    <head>
        <meta charSet="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack.js"/>
        <script src="/_next/static/chunks/main-app.js" async=""></script>
        <script src="/_next/static/chunks/app-pages-internals.js" async=""></script>
        <meta name="robots" content="noindex"/>
        <meta name="next-error" content="not-found"/>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app"/>
        <meta name="next-size-adjust"/>
        <script src="/_next/static/chunks/polyfills.js" noModule=""></script>
    </head>
    <body>
        <script src="/_next/static/chunks/webpack.js" async=""></script>
        <script>
            (self.__next_f = self.__next_f || []).push([0]);
            self.__next_f.push([2, null])
        </script>
        <script>
            self.__next_f.push([1, "1:HL[\"/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/_next/static/css/app/layout.css?v=1700007430527\",\"style\"]\n0:\"$L3\"\n"])
        </script>
        <script>
            self.__next_f.push([1, "4:I[\"(app-pages-browser)/./node_modules/next/dist/client/components/app-router.js\",[\"app-pages-internals\",\"static/chunks/app-pages-internals.js\"],\"\"]\n6:I[\"(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js\",[\"app-pages-internals\",\"static/chunks/app-pages-internals.js\"],\"\"]\n7:I[\"(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js\",[\"app-pages-internals\",\"static/chunks/app-pages-internals.js\"],\"\"]\n8:I[\"(app-pages-browser)/./node_modules/next/dist/clien"])
        </script>
        <script>
            self.__next_f.push([1, "t/components/render-from-template-context.js\",[\"app-pages-internals\",\"static/chunks/app-pages-internals.js\"],\"\"]\n"])
        </script>
        <script>
            self.__next_f.push([1, "3:[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/app/layout.css?v=1700007430527\",\"precedence\":\"next_static/css/app/layout.css\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"buildId\":\"development\",\"assetPrefix\":\"\",\"initialCanonicalUrl\":\"/api/hello\",\"initialTree\":[\"\",{\"children\":[\"__DEFAULT__\",{}]},\"$undefined\",\"$undefined\",true],\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$L5\"],\"globalErrorComponent\":\"$6\",\"children\":[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_e66fe9\",\"children\":[\"$\",\"$L7\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L8\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[],\"childProp\":{\"current\":[\"$L9\",\"$La\",null],\"segment\":\"__DEFAULT__\"},\"styles\":null}]}]}],null]}]]\n"])
        </script>
        <script>
            self.__next_f.push([1, "a:E{\"digest\":\"NEXT_NOT_FOUND\",\"message\":\"NEXT_NOT_FOUND\",\"stack\":\"Error: NEXT_NOT_FOUND\\n    at notFound (webpack-internal:///(rsc)/./node_modules/next/dist/client/components/not-found.js:23:19)\\n    at NoopParallelRouteDefault (webpack-internal:///(rsc)/./node_modules/next/dist/client/components/parallel-route-default.js:13:28)\\n    at eO (/Users/mishamoroshko/temp/nextjs-pdfmake-issue/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:261871)\\n    at /Users/mishamoroshko/temp/nextjs-pdfmake-issue/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:274673\\n    at Array.toJSON (/Users/mishamoroshko/temp/nextjs-pdfmake-issue/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:279443)\\n    at stringify (\u003canonymous\u003e)\\n    at /Users/mishamoroshko/temp/nextjs-pdfmake-issue/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:265799\\n    at ez (/Users/mishamoroshko/temp/nextjs-pdfmake-issue/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:265878)\\n    at eH (/Users/mishamoroshko/temp/nextjs-pdfmake-issue/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:266279)\\n    at Timeout._onTimeout (/Users/mishamoroshko/temp/nextjs-pdfmake-issue/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:262777)\\n    at listOnTimeout (node:internal/timers:569:17)\\n    at process.processTimers (node:internal/timers:512:7)\"}\n"])
        </script>
        <script>
            self.__next_f.push([1, "5:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"Create Next App\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Generated by create next app\"}],[\"$\",\"meta\",\"4\",{\"name\":\"next-size-adjust\"}]]\n9:null\n"])
        </script>
        <script>
            self.__next_f.push([1, ""])
        </script>
    </body>
</html>

About this issue

  • Original URL
  • State: open
  • Created 8 months ago
  • Reactions: 7
  • Comments: 17

Most upvoted comments

Hi I have fixed the issue please check and review : https://github.com/moroshko/nextjs-pdfmake-issue/pull/1

Same issue here using nextjs@14 route handlers.

import PdfMake from "pdfmake";

export async function GET() {
  const pdfMake = new PdfMake({});
  console.log(pdfMake);
  return Response.json({ data: "ok" });
}

This will return a 404 page on nextjs. However if i remove const pdfMake = new PdfMake({}); the route handlers correctly displays the json response. At this point i feel like this is a problem with nextjs.

Let’s hope this gets fixed asap.

Did some more digging and found out that next build produces an error instead of just swallowing it into a 404:

~/dir/web (h2b-layout ✗) pnpm run build

> web@0.1.0 build dir/web
> next build

   ▲ Next.js 14.0.3
   - Environments: .env

 ✓ Creating an optimized production build
 ✓ Compiled successfully
 ✓ Linting and checking validity of types
   Collecting page data  ..Error: ENOENT: no such file or directory, open 'dir/web/.next/server/app/api/[uuid]/generate/data.trie'
    at Object.openSync (node:fs:603:3)
    at Object.readFileSync (node:fs:471:35)
    at 22318 (dir/web/.next/server/app/api/[uuid]/generate/route.js:1:101599)
    at t (dir/web/.next/server/webpack-runtime.js:1:143)
    at 96985 (dir/web/.next/server/app/api/[uuid]/generate/route.js:1:234192)
    at t (dir/web/.next/server/webpack-runtime.js:1:143)
    at 50301 (dir/web/.next/server/app/api/[uuid]/generate/route.js:14:202634)
    at t (dir/web/.next/server/webpack-runtime.js:1:143)
    at 40620 (dir/web/.next/server/app/api/[uuid]/generate/route.js:14:202784)
    at t (dir/web/.next/server/webpack-runtime.js:1:143) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: 'dir/web/.next/server/app/api/[uuid]/generate/data.trie'
}

> Build error occurred
Error: Failed to collect page data for /api/[uuid]/generate
    at dir/web/node_modules/.pnpm/next@14.0.3_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:1217:15
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  type: 'Error'
}
   Collecting page data  . ELIFECYCLE  Command failed with exit code 1.

Which in turn has lead here to this PDFKit issue: https://github.com/bpampuch/pdfmake/issues/2455

Which then leads to a 4 year old webpack example… this is still a bug on Next.js side, as a route compilation failure should not go to a 404, but to fix our problem with pdfmake seems like we’re gonna need a custom webpack