next-on-pages: [๐Ÿ› Bug]: middleware crashes if sentry installed under src directory

next-on-pages environment related information

Happens when deploying to preview but also can be reproduced locally:

System: Platform: linux Arch: x64 Version: #1 SMP Fri Jan 27 02:56:13 UTC 2023 CPU: (24) x64 AMD Ryzen 9 3900X 12-Core Processor Memory: 16 GB Shell: /bin/bash Binaries: Node: 18.16.0 Bun: N/A pnpm: 8.6.9 Yarn: 1.22.19 npm: 9.8.1 Package Manager Used: pnpm Relevant Packages: @cloudflare/next-on-pages: 1.5.0 vercel: 31.2.2 next: 13.4.14-canary.0

Description

When using middleware with an array matcher: ['/blog'] pages immediately crashes with

[mf:inf] HEAD /_next/data/1oj9J4jAV41enV60HBD1V/en/blog.json 500 Internal Server Error (4ms)
TypeError: edgeFunction.default is not a function
    at runOrFetchBuildOutputItem (fh03bwcwbs.js:731:42)
    at async RoutesMatcher.runRouteMiddleware (fh03bwcwbs.js:1006:18)
    at async RoutesMatcher.checkRoute (fh03bwcwbs.js:1127:21)
    at async RoutesMatcher.checkPhase (fh03bwcwbs.js:1169:22)
    at async RoutesMatcher.run (fh03bwcwbs.js:1203:20)
    at async findMatch (fh03bwcwbs.js:1221:18)
    at async handleRequest (fh03bwcwbs.js:1217:17)
    at async jsonError (fh03bwcwbs.js:1363:12) {
  stack: TypeError: edgeFunction.default is not a function
โ€ฆ7)
    at async jsonError (fh03bwcwbs.js:1363:12),
  message: edgeFunction.default is not a function
}

This is valid syntax according to https://nextjs.org/docs/app/building-your-application/routing/middleware#matching-paths

Changing to single string like matcher: '/blog' works fine.

I was trying to deploy

matcher: ['/', '/((?!_next|favicon.ico|api|.*\\.).*)', '/api/login', '/api/logout']

was able to work around it by doing something like this but

matcher: '/$|/((?!_next|favicon\\.ico|api|.*\\..*).*))$|/api/login$|/api/logout$',

Reproduction

Create a middleware file with an matcher containing an array and deploy to next-on-pages:

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
export function middleware(request: NextRequest) {
  return NextResponse.next();
}
 
export const config = {
  matcher: ['/about']
}

Note immediate 500 error. Change to matcher: '/about' and redeploy and everything will work fine.

Pages Deployment Method

Pages CI (GitHub/GitLab integration)

Pages Deployment ID

https://37487ae9.t3-challenge.pages.dev

Additional Information

If you are running minified, the error is:

TypeError: (intermediate value).default is not a function
    at k (xxpe9e4ms1j.js:363:55)
    at async w.runRouteMiddleware (xxpe9e4ms1j.js:515:13)
    at async w.checkRoute (xxpe9e4ms1j.js:554:69)
    at async w.checkPhase (xxpe9e4ms1j.js:579:15)
    at async w.run (xxpe9e4ms1j.js:603:13)
    at async G (xxpe9e4ms1j.js:612:10)
    at async z (xxpe9e4ms1j.js:608:50)
    at async jsonError (xxpe9e4ms1j.js:701:12) {
  stack: TypeError: (intermediate value).default is not a fโ€ฆ0)
    at async jsonError (xxpe9e4ms1j.js:701:12),
  message: (intermediate value).default is not a function
}

Would you like to help?

  • Would you like to help fixing this bug?

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 18 (11 by maintainers)

Most upvoted comments

I donโ€™t see this anymore so closing!

@dario-piotrowicz Nice thank you so much for verifying! ๐Ÿ˜ƒ

@lforst I see, that sounds reasonable

Iโ€™m sorry you have to jump through these hoops to allow you code to run on our runtime ๐Ÿ˜”

Thank you so very much again, if you need anything Iโ€™m always here ๐Ÿ™‚

Hi @lforst thank you so so very much for being keen to help out! โค

If you could generate the id on the server as you mentioned that could fix this, but it might not work and there could be a simpler solution, so let me give you a bit of context here.

The issue with our runtime here is that when we import a dynamic file the imported code is run in a separate context and not the context related to the request handing. Such a context is one that in theory can leak across different requests handling, as such it cannot contain any sort of random or instance related values, it cannot make external http requests also, basically it should only contain sort of global static values that are safe to be reused within different requests handling.

It can contain functions since those when invoked are run inside the current context (which in our case will be the request handling one).

So I donโ€™t think that using a different generation method can help, and the server side id generation can help but only as long as that doesnโ€™t require an extra fetch run at the exact same time/place as the current id generation.

So as a first step Iโ€™d like to ask you if you could check where the id is generated, is the generation done inside some function/method and not at the top level of a file? If itโ€™s not inside a function/method could you try moving it into one? (If it already is then the issue could be generated by vercels/our build process so weโ€™d have to find a different solution and/or go with the server side idea)

PS: Thanks so very much again, Iโ€™m ultra keen to help however I can to make this work, so please donโ€™t hesitate on asking me anything (also unfortunately Iโ€™m away this week so Iโ€™m going to be a bit limited on how much I can help in the next few days ๐Ÿ™‡)

@dario-piotrowicz Hi, Sentry SDK maintainer here. Do you know any safe methods we can call to generate IDs? ID generation on the client is at the core of the Sentry architecture so we have the appetite to fix this ๐Ÿ˜„

(EDIT: Ok I had a conversation and apparently we can get around generating an ID and our servers will generate one. Weโ€™ll take a look what we can do.)

Thanks a lot @Enalmada the reproduction is extremely helpful! ๐Ÿ™ โค๏ธ

Iโ€™m looking into this, I think I understand where the issue lies but I still need to investigate to make sure, and also to find hopefully a solution

Iโ€™ll update you when there are some news

(PS: sorry for the late reply ๐Ÿ™‡)

Thanks @dario-piotrowicz for your time in looking into this. I am on a windows machine using WSL which might have something to do with local reproduction, although that wouldnโ€™t explain why just changing that array to string causes the github ci/cd build to deploy something that suddenly works. I will get a reproduction going.

No problem ๐Ÿ™‚

yeah I am not really sure, maybe in your project there could be a specific combination of things that make that error? ๐Ÿคท

a reproduction would be really great if you could manage that ๐Ÿ™‡