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)
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 ๐)
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 ๐