Running into some cryptic error. Help needed.
I am running into some error. This is on React 19, Nextjs 15 and all latest Convex. Has anyone seen this?

54 Replies
Any chance you're using Cloudflare? This React bug mentions Astro specifically but looks very similar: https://github.com/facebook/react/issues/31827
Hmm might not even be cloudflare specific, I think the error message just came from a cloudflare worker that was doing ssr maybe
This has popped up in a few other places with different tooling. MessageChannel is a Node API used for SSR, so this error is happening in a non-node context. Another maybe related issue here that does involve Next 15: https://github.com/resend/react-email/issues/1630
This comment from a Vercel team member seems to hit the root of the issue: https://github.com/vercel/next.js/issues/71865#issuecomment-2444377726
Thank you. Looking into all the links you shared now.
interesting that you're getting the same error from next (presumably in a vercel environment) and from the convex environment. neither of them implement MessageChannel. any idea why you might be importing "react-dom/server"?
Ah. Yes. That's interesting.
@erquhart , you saved the day. After much debugging, uninstalling and re-installing, react-email was indeed the culprit. Things worked once I commented out, and used pure html.

I initially tried jsx-email, but that had a bun of node things that made convex unhappy.
hmm i think we want "react-email" to work. we'll look into it. can you share the exact version of react-email and react-dom and other packages that may be relevant (
npm ls
) 🙏Ah. It was not just react-email. Even after I removed react email, attempting to pass anything to the react prop of resend, triggered the same error. Just spent the last hour converting all to pure html with the help of claude. Then using the html prop instead with getSomeTemplate, which returns a html string. No errors. But If I pass the same html to the react prop, it shows the same error
I just updated all our packages. So the latest of all relevant package. The only react in the api folder is from resend and react-email. So its def something with react. Once I got rid of that, all works now
For example, the below does not work

Sounds like react 19 specifically
Yes
This works:

@erquhart Yes. React 19.
Hi! I just ran into this exact issue tonight while trying to install and use react-email. Was there a solution identified?
Yeah, not using react. There’s a non-working and working example above
RIP
I love the simplicity of Convex Auth but might need to switch to Clerk
Just want to flag that we're having the same issue here, going for pure html for now, but would love to get updates if React 19 works at some point
Thanks for flagging, how would you describe the issue @David Alonso, "React emails don't work with React 19 in Convex?" Sounds like it's to do with some Node.js specific APIs?
Sounds like we need to prioritize this, but I don't know what the issue is yet. If it's a general runtime API we can add it, but if the issue is that React Email now only supports Node.js for React 19 that's something we need to open an issue about
ok looks like https://github.com/resend/react-email/issues/1630
GitHub
Error: A Node.js API is used (MessageChannel) which is not supporte...
Describe the Bug Using React 19 + Next.js 15 I want to use @react-email/render on edge runtime. However, I got this error: unhandledRejection: Error: A Node.js API is used (MessageChannel) which is...
yeah that's how I'd describe it but only based on what solved it for me, which was downgrading to react 18.3 (which is what the auth template uses). I briefly tried the pure HTML approach but that didn't seem to work for me (i might have missed something)
So two issues and solutions:
1. MessageChannel not supported: use a node action.
2. reactDOMServer.default.renderToPipeableStream is undefined: Add @react-email/components (or /render, whichever you import render from) to node.externalPackages in convex.json
So the status is "React emails work with React 19 in Convex, but only for Node actions".
It is possible to use the Convex runtime, but the @react-email/render browser module is attempting to run
reactDOMServer.renderToReadableStream
when the actual import shape is reactDOMServer.default.renderToReadableStream
. Works when patched. Going to see if there's an elegant solution, otherwise might make a patch-package for this.
Here's the patch steps for anyone that wants this working in Convex runtime (patch below):
- Make sure you're using @react-email/render 1.0.5 (or @react-email/components 0.0.35, which exports render from the same version)
- Add the file above to a patches/ directory alongside your package.json (repo or project root)
- Set up patch package to apply: https://www.npmjs.com/package/patch-package
/patches/@react-email+render+1.0.5.patch
@Michael
Forgot to add, in Convex runtime I think you still need to polyfill
MessageChannel
, just put the MessageChannel mock below in a file and import it first in whatever file your email rendering is happening in. You may be able to get away with a more minimal polyfill but this one works.
Super helpful! I'm now using "@react-email/render": "1.1.0" and having the same issue - Do i need to set my version to 1.0.5 to apply the patch? And is this something that will end up getting fixed or will I need the patch forever?
After doing some more reading - is there a recommended way to use @react-email/components with resend + convex-auth? Would love to get that set up in my new app
I was using the convex auth example repo - but it didn't have anything about this issue 😕
Just saw your response today about a PR for patching it 🙂 I'll keep my eyes peeled for that and save that work for later 👍
Yeah it's complicated. There's an effort to provide an edge-light distro that would remove the need for a polyfill: https://github.com/resend/react-email/pull/2222
The default export issue has a PR open to but I'm having trouble finding it. At any rate, if you want to get this working I'd pin to 1.0.5 for now and use the fixes above. Otherwise hopefully fixes get in place soon.
Thanks for the context! We probably won’t go live with the product for another 6 weeks so I’ll wait to see if it gets fixed 😀😀
Have you by any chance created a working example for your better-auth + Convex implementation that shows how to send verification and password reset emails using Resend and React Email? I applied the patch following your guide correctly, but I am still getting a "MessageChannel is not defined" error.
Yessir: https://github.com/erquhart/convex-better-auth/tree/main/examples/next
For anyone that's still seeing the MessageChannel undefined issue after adding the polyfill: the polyfill must be imported before the other imports. The polyfill can't be inlined above the imports, it will still execute after the imports.
I ran that patch and I'm getting this error
@erquhart
Ah, I don't think patch-package works with pnpm
pnpm supports patching natively: https://pnpm.io/cli/patch
pnpm patch <pkg> | pnpm
Prepare a package for patching (inspired by a similar command in Yarn).
I haven't used it, but if you follow their patching instructions you can try manually using the patch I shared above to make the changes.
I tried to remove pnpm from the project. and for some reason it's still trying to use the pnpm package
If you want to drop pnpm, deleting node_modules and pnpm-lock.yaml should do it
I removed every reference of pnpm from the project and did a completely fresh npm install and it is still using pnpm for that function
Convex runtime wasn't running 🤦♂️
ah that'll do it
working now?
Following up here since I just ran into the same issue with Better Auth, Resend, React Email, and Convex (
MessageChannel is not defined
). This is what fixed it for me:
1. Add convex.json
at the root and specify @react-email/render
as an external package:
2. Add an override
in package.json
for @react-email/render
. The latest version has fixed the renderToPipeableStream
issue described above, however, the latest versions of react-email
and @react-email/components
don't yet rely on up-to-date @react-email/render
... so you have to override it manually:
3. Add the MessageChannel
polyfill as described by @erquhart here: https://github.com/resend/react-email/issues/1630#issuecomment-2773421899 (I created a polyfills.ts
file within convex/
and then added import "./pollyfills"
to the top of convex/auth.ts
I think that's it! Hopefully we can remove the polyfill and override at some point in the future, but at least no package patch is required now.GitHub
Error: A Node.js API is used (MessageChannel) which is not supporte...
Describe the Bug Using React 19 + Next.js 15 I want to use @react-email/render on edge runtime. However, I got this error: unhandledRejection: Error: A Node.js API is used (MessageChannel) which is...
This has worked for me. Thank you @Eva!
Much better than using patch-package, thanks for the update
Update: only the polyfill is needed if you're on the latest version of the
@react-email/*
libs (step 3 from Eva's last comment), no convex.json or dependency overrides required. The polyfill will unfortunately be required indefinitely, the fix is currently at a standstill: https://github.com/resend/react-email/pull/2225Thank you so much for the fix, I was trying to debug it for hours...
It works now!
Hi everyone. Im in need of help. I have inserted this code in the polyfills.ts last week and then I imported polyfills.ts in convex/auth.ts. It was working well until today. I got an error in convex logs saying . Anyone has any idea on how to fix this?
That should mean you somehow ended up running an older version of @react-email/render. You can run
npm ls @react-email/render
to be sure, should be at least 1.1.2Thank you
Just ran into this issue and my workaround was as shown in this picture, I am use 'use node' directive and then I replaced internalMutation to internalAction, have all the latest packages





does anyone has any idea why?
Wherever you're sending the email from, the polyfill isn't getting imported

Is this not enought?


This part of being unable to setup a basic auth with otp is getting frustating
@erquhart any ideias?
I can upload my code to github is that helps
Hard to say, but there's a working implementation here, maybe you can compare and contrast (it's better-auth, but the problem you're hitting should apply to convex auth as well): https://github.com/get-convex/better-auth/blob/main/examples/react/convex/email.tsx
Oh we migrated that to the Resend component - that also works, but here's how it looked when using Resend directly: https://github.com/get-convex/better-auth/blob/7991bc7ffb182fb5da0abf72618a49fb5d42a1ae/examples/react/convex/email.tsx