Remix Convex Vercel
Dev environment runs great. I have chosen to use HttpClient since I struggled to set up the ReactClient in Remix with out docs and am fine with non-reactive data.
Deploying to vercel and the app builds and deploys, both Remix and Convex. Any Remix pages that don't have a loader or action calling the HttpClient render as expected. Any that do use HttpClient crash the app - however I am able to log server side the expected response from the HttpClient in the remix action... So they are talking
Currently adding more error logging to debug but the error I'm getting is
"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"TypeError: First parameter has member 'readable' that is not a ReadableStream."
16 Replies
The server logs from vercel:
NOV 28 12:45:36.23
-
my-domain.vercel.app
[POST] /admin/login
Unknown application error occurred Runtime.Unknown
NOV 28 12:45:35.96
-
my-domain.vercel.app
[POST] /admin/login
Unhandled Promise Rejection {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"TypeError: First parameter has member 'readable' that is not a ReadableStream.","reason":{"errorType":"TypeError","errorMessage":"First parameter has member 'readable' that is not a ReadableStream.","stack":["TypeError: First parameter has member 'readable' that is not a ReadableStream."," at assertReadableStream (/var/task/node_modules/web-streams-polyfill/dist/ponyfill.js:362:19)"," at convertReadableWritablePair (/var/task/node_modules/web-streams-polyfill/dist/ponyfill.js:3524:9)"," at ReadableStream.pipeThrough (/var/task/node_modules/web-streams-polyfill/dist/ponyfill.js:3608:29)"," at fetchFinale (node:internal/deps/undici/undici:11082:56)"," at mainFetch (node:internal/deps/undici/undici:10974:9)"," at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection: TypeError: First parameter has member 'readable' that is not a ReadableStream."," at process.<anonymous> (file:///var/runtime/index.mjs:1276:17)"," at process.emit (node:events:529:35)"," at emit (node:internal/process/promises:149:20)"," at processPromiseRejections (node:internal/process/promises:283:27)"," at process.processTicksAndRejections (node:internal/process/task_queues:96:32)"]}
NOV 28 12:45:35.96
-
my-domain.vercel.app
[POST] /admin/login
res from Convex User not found
Here is the try-catch in the action that is failing and it's not running the catch which is more strange. The last request in the vercel logs is the top one at /admin/login so we never successfully redirect?
try {
const convex = new ConvexHttpClient(process.env.CONVEX_URL ?? "");
const userLogIn = await convex.action(api.auth.loginUser, {email, password});
console.log("res from Convex", userLogIn);
if (typeof userLogIn === 'object' && userLogIn.status === 'Login successful') {
return new Response(null, {
headers: {
'Set-Cookie':
auth=${userLogIn.token}; HttpOnly; Path=/; SameSite=Strict,
'Location': '/admin',
},
status: 302,
});
}
return userLogIn;
} catch (error) {
console.error("Error calling Convex API:", error);
return new Response('Error processing request', {
status: 500,
headers: {
"Content-Type": "text/plain",
},
});
}
I'm using node 18 on vercel and dev - I imagine it has to do with version issue?@Itsacoup do other fetch requests work? eg if you try
fetch("http://www.example.com")
does that cause the same error in the route?
Know if this is running in the Vercel edge runtime or Node.js?
The http client has the ability to use a custom fetch, see https://github.com/get-convex/convex-js/blob/32ff1dc1190e35223bda44c41f51a237960da3e0/src/browser/http_client.ts#L26
GitHub
convex-js/src/browser/http_client.ts at 32ff1dc1190e35223bda44c41f5...
TypeScript/JavaScript client library for Convex. Contribute to get-convex/convex-js development by creating an account on GitHub.
The global fetch() provided should be being used in Node.js 18: https://github.com/get-convex/convex-js/blob/32ff1dc1190e35223bda44c41f51a237960da3e0/src/browser/http_client-node.ts#L3
GitHub
convex-js/src/browser/http_client-node.ts at 32ff1dc1190e35223bda44...
TypeScript/JavaScript client library for Convex. Contribute to get-convex/convex-js development by creating an account on GitHub.
@Itsacoup are you interested in getting the React client working? I'm using Remix with the Convex React client; it works great and I'd be happy to share some code if you'd like.
Running a fetch in the action in place of await convex.httpClient. I hit a test endpoint and get answer back and the app doesn't crash?
RJ this is great to here, are you deployed on Vercel?
And I've did basic vercel configurations - none 18, haven't defined any edge functions. using @vercel/remix package
Actually this is the response i get back from the fetch
Response {
size: 0,
[Symbol(Body internals)]: {
body: ReadableStream {
_state: 'readable',
_reader: undefined,
_storedError: undefined,
_disturbed: false,
_readableStreamController: [ReadableStreamDefaultController]
},
type: null,
size: null,
boundary: null,
disturbed: false,
error: null
},
.....
}
RJ one of the draw backs of the ReactClient is the lack of SSR - this is an ecommerce site so I chose to use HttpClient and server render most pages
All this being said, I'm leaning towards this being a remix issue on vercel. My set up worked great on Dev. Loving convex btwI'm using Netlify, but for the React client it shouldn't really matter.
Here's the idea:
But if you need SSR, then agreed that you do probably want to get the HTTP client working either way!
Awesome thanks for sharing.
As for the error I'm facing. It appears to be a known issue with Remix on vercel. Most of the issues appear resolved due to a patch last month... But I'm still dealing with it 🫠gonna investigate in Remix discord
https://discord.com/channels/770287896669978684/1166834027228041297
@Itsacoup thanks for investigating, if you can find a fetch() that works (e.g. node-fetch) and call setFetch() with it hopefully that makes things work.
No problem, thanks for sharing your research as well!
@itsaBrandon reading that issue, it sounds like they think they've fixed it; since you're seeing the issue with the Convex HTTP client but not with a normal fetch, maybe the way they fixed it was swapping out fetch at a later point. If they do that then this
let localFetch = fetch
would be a problem, it could still be using the old broken fetch? You might try calling setFetch(fetch)
each time before you call fetch. If this is the issue we can fix this.@ballingt first thanks for the support trying to figure this out!
But regarding your suggestion I guess I'm a little confused. What is the fetch that I'm trying to set?
I tried using just fetch API on a test endpoint (JSON placeholder) which did resolve. But the code I actually want to run accesses resources through the http client using generated API as an arg (e.g.
api.auth.checkAuth
< the function resource)
Is there resources/endpoint exposed from the generated API that I could hand into fetch() or am I missing something?The Convex HTTP client exports a
setFetch()
function that you can use to choose the fetch implementation that is uses
It's possible that calling this setFetch()
function with the global fetch would be an improvement because currently whatever the global fetch is at import time is used.
This is just a guess based on the behavior you see of fetch()
calls working, but the Convex HTTP client not working. That seems pretty weird to me and all I can think of is that what the global fetch function is changes between import time and when you use it.Only able to import it from node_modules directly
import { setFetch } from "node_modules/convex/dist/esm-types/browser/http_client";
This leads to a rutime error
[ERROR] Could not resolve "node_modules/convex/dist/esm-types/browser/http_client"
app/routes/_index.tsx:31:25:
31 │ ...ch } from "node_modules/convex/dist/esm-types/browser/http_clie...
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "node_modules/convex/dist/esm-types/browser/http_client" as external to exclude it from the bundle, which will remove this error.
Tried adding to serverDependenciesToBundle in remix.config (transpile) but doesn't resolve it. I'm going to keep pushing on the vercel/remix front. Requests to convex resolve cause I can log the responses and see them in the vercel server log - yet I still get this error and it's only on pages with action/loaders that use the httpclient so theres a connection there....Ah shoot, I didn't realize it wasn't exposed!
We'll either expose this in the next client release of fix the issue
@ballingt update for ya on this. The closed issue on vercel/remix https://github.com/vercel/remix/issues/62 got replied to, and they may take a look.
I build a demo app https://convex-remix-demo.vercel.app/ with minimal code and replicated the error. https://github.com/baberMatt/convex-remix-demo