BakemonoHouse
BakemonoHouse•5mo ago

fetchQuery fails inside clerkMiddleware (clerk/nextjs)

I'll add a screenshot once I land, as I just found this issue right before boarding a flight. It seems that fetchQuery fails (with or without token added) when called inside the new clerkMiddleware (replacing their authMiddleware). Anyone have experience with fetchQuery inside nextjs middleware? I've checked the auth().getToken({ template: "convex" }) returning a proper token.
18 Replies
BakemonoHouse
BakemonoHouseOP•5mo ago
error is propagating from http_client, no error message available, only returning stack trace. same code was functioning correctly when using authMiddleware. issue only happening after changing to clerkMiddleware.
Michal Srb
Michal Srb•5mo ago
Hmm, this sounds similar to https://discord.com/channels/1019350475847499849/1269683954772869182/1270452486888751268 If you're getting a similar message, you can find what failed on the Convex dashboard (you can search by Request ID)
BakemonoHouse
BakemonoHouseOP•5mo ago
Hi @Michal Srb it turns out, it was the problem related to Vercel's incident yesterday. This was why the error was not traceable from both the logs and convex dashboard. Ok sorry, I'm back and I'm not 100% sure if this is Vercel's problem again. I've raised a ticket there as well: Situation:
await fetchQuery(api.foo.bar, {}, { token });
await fetchQuery(api.foo.bar, {}, { token });
was returning an empty error in vercel log. api.foo was never triggered (I've checked this on multiple level) so I tried using the ConvexHttpClient (set up correctly with the url and auth). then I ended up trying native fetch to mimic the behavior of
fetchQuery()
fetchQuery()
function. - This works perfectly fine (fetchQuery, client.query, fetch) on localhost. - Inside the Vercel Middleware however, I see 404 response with empty body (which is why the error was empty, because it is written to
throw new Error(await response.text());
throw new Error(await response.text());
which is an empty string. Tried with
mode: "cors"
mode: "cors"
and
mode: "no-cors"
mode: "no-cors"
. same result, works perfectly fine on localhost but not on vercel middleware. I'm leaving this here just in case others are experiencing same on the middleware or server actions of Vercel. funny thing is clerk requests are working fine. just the convex requests are returning 404.
BakemonoHouse
BakemonoHouseOP•5mo ago
adding the response from vercel.
No description
BakemonoHouse
BakemonoHouseOP•5mo ago
Hi @Michal Srb seems like this issue needs to be reopened. Both myself and Vercel replicated the issue and seems it is Convex returning 404. Can't figure out what is exactly causing the 404 at the moment.
sujayakar
sujayakar•5mo ago
hey @BakemonoHouse, I've started trying to get a repro on our side. I'm starting with a Vercel edge function and it appears to work in both dev and when deployed to vercel:
export const dynamic = "force-dynamic";
export const runtime = "edge";

import { fetchQuery } from "convex/nextjs";
import { anyApi } from "convex/server";

const api = anyApi;

export async function GET(request: Request) {
const results = await fetchQuery(api.messages.list, {});
return new Response(
`Hello from ${process.env.VERCEL_REGION}: ${JSON.stringify(results)}`
);
}
export const dynamic = "force-dynamic";
export const runtime = "edge";

import { fetchQuery } from "convex/nextjs";
import { anyApi } from "convex/server";

const api = anyApi;

export async function GET(request: Request) {
const results = await fetchQuery(api.messages.list, {});
return new Response(
`Hello from ${process.env.VERCEL_REGION}: ${JSON.stringify(results)}`
);
}
(next 14.2.5, convex 1.14.0) https://vercel-edge-demo-jugrhlcte-sujayakars-projects.vercel.app/hello works (after configuring NEXT_PUBLIC_CONVEX_URL). I'm going to try using edge middleware next.
BakemonoHouse
BakemonoHouseOP•5mo ago
Yup I've checked NEXT_PUBLIC_CONVEX_URL exists (in case this needs validation) I'm on convex 1.14.0 next 14.2.3
sujayakar
sujayakar•5mo ago
okay! i have a repro with middleware. interesting that edge functions work but middleware doesn't.
// src/middleware.ts

import { fetchQuery } from "convex/nextjs";
import { anyApi } from "convex/server";
import { NextResponse } from "next/server";

// Trigger this middleware to run on the `/secret-page` route
export const config = {
matcher: "/secret-page",
};

export default async function middleware(request: Request) {
console.log(`Visitor from ${JSON.stringify((request as any).geo)}`);
const results = await fetchQuery(anyApi.messages.list, {});
console.log(`Messages: ${JSON.stringify(results)}`);

// Rewrite to URL
return NextResponse.rewrite(request.url);
}
// src/middleware.ts

import { fetchQuery } from "convex/nextjs";
import { anyApi } from "convex/server";
import { NextResponse } from "next/server";

// Trigger this middleware to run on the `/secret-page` route
export const config = {
matcher: "/secret-page",
};

export default async function middleware(request: Request) {
console.log(`Visitor from ${JSON.stringify((request as any).geo)}`);
const results = await fetchQuery(anyApi.messages.list, {});
console.log(`Messages: ${JSON.stringify(results)}`);

// Rewrite to URL
return NextResponse.rewrite(request.url);
}
fails at https://vercel-edge-demo-6uydre4fe-sujayakars-projects.vercel.app/secret-page i'll look at the logs on our side
BakemonoHouse
BakemonoHouseOP•5mo ago
const headers = { "Content-Type": "application/json", "Convex-Client": "npm-1.14.0", "Authorization": Bearer ${token}, }; const response = await fetch(${process.env.NEXT_PUBLIC_CONVEX_URL!}/api/query, { method: "POST", headers, body: JSON.stringify({ path: "users:checkMe", args: {}, format: "json" }) }); console.info("from middleware", ${process.env.NEXT_PUBLIC_CONVEX_URL!}/api/query, response.ok, response.status); if (!response.ok && response.status !== 560) { console.error(response.status, await response.text()); } else { console.info("success", await response.json()) } yup i went down to this level to test. only breaks in the middleware. super weird
sujayakar
sujayakar•5mo ago
cool, that's super helpful ^^
BakemonoHouse
BakemonoHouseOP•5mo ago
haha it should rule out the convexclient issues. I read through the whole node_module to test... thanks for helping out!
sujayakar
sujayakar•5mo ago
okay, I've made some progress. for some reason, middleware includes the Forwarded header in the request (in addition to X-Forwarded-For) while edge functions do not. I'm still digging, but including the Forwarded header is causing a layer in our system to reject the request with a 404.
BakemonoHouse
BakemonoHouseOP•5mo ago
should I relay this back to Vercel team for more details?
sujayakar
sujayakar•5mo ago
I think the issue is on our side (adding the Forwarded header shouldn't cause us to return 404), but it's definitely interesting. here's an example of a "bad" request on my test app that includes both Forwarded and the X-Forwarded-* headers:
{'Accept-Encoding': ['gzip'],
'Cdn-Loop': ['cloudflare; subreqs=1'],
'Cf-Connecting-Ip': ['2a06:98c0:3600::103'],
'Cf-Ew-Via': ['15'],
'Cf-Ray': ['8b08c297f17213b1-IAD'],
'Cf-Visitor': ['{"scheme":"https"}'],
'Cf-Worker': ['cloudflare-workers.vercel-infra-production.com'],
'Content-Length': ['67'],
'Content-Type': ['application/json'],
'Convex-Client': ['npm-1.14.0'],
'Forwarded': ['for=204.48.36.234;host=vercel-edge-demo-6uydre4fe-sujayakars-projects.vercel.app;proto=https'],
'User-Agent': ['Vercel Edge Functions'],
'X-Forwarded-For': ['2a06:98c0:3600::103'],
'X-Forwarded-Proto': ['https'],
'X-Middleware-Subrequest': ['adebd40afe7557319e160b865e0e202e8637c449'],
'X-Vercel-Id': ['iad1::ldlnq-1723217140212-30fa9f3a46d4']}
{'Accept-Encoding': ['gzip'],
'Cdn-Loop': ['cloudflare; subreqs=1'],
'Cf-Connecting-Ip': ['2a06:98c0:3600::103'],
'Cf-Ew-Via': ['15'],
'Cf-Ray': ['8b08c297f17213b1-IAD'],
'Cf-Visitor': ['{"scheme":"https"}'],
'Cf-Worker': ['cloudflare-workers.vercel-infra-production.com'],
'Content-Length': ['67'],
'Content-Type': ['application/json'],
'Convex-Client': ['npm-1.14.0'],
'Forwarded': ['for=204.48.36.234;host=vercel-edge-demo-6uydre4fe-sujayakars-projects.vercel.app;proto=https'],
'User-Agent': ['Vercel Edge Functions'],
'X-Forwarded-For': ['2a06:98c0:3600::103'],
'X-Forwarded-Proto': ['https'],
'X-Middleware-Subrequest': ['adebd40afe7557319e160b865e0e202e8637c449'],
'X-Vercel-Id': ['iad1::ldlnq-1723217140212-30fa9f3a46d4']}
BakemonoHouse
BakemonoHouseOP•5mo ago
yup I did assume so too. glad to be narrowing this down 🙂
sujayakar
sujayakar•5mo ago
okay, we reverted a routing change on our side, and my repro now works. @BakemonoHouse, can you see if it's fixed for you too?
BakemonoHouse
BakemonoHouseOP•5mo ago
let me try yup it has been resolved thanks a lot!
sujayakar
sujayakar•5mo ago
of course! thanks for your patience and working together with us on this bug.

Did you find this page helpful?