-
Notifications
You must be signed in to change notification settings - Fork 38
projects.addProjectDomain throws UnexpectedClientError with reused Request in Next.js server runtime #238
Description
Summary
Calling vercel.projects.addProjectDomain() in a Next.js server runtime throws:
UnexpectedClientError: Unexpected HTTP client error: TypeError: Cannot construct a Request with a Request object that has already been used.This happened for us while implementing storefront domain management in a Next.js app router app.
Version
@vercel/sdk:1.19.11- Node:
24.11.1 - Next.js app router server runtime
- macOS local dev, but the failure appears tied to the runtime/fetch implementation rather than our domain logic
Failing call
await vercel.projects.addProjectDomain({
idOrName: projectId,
teamId,
requestBody: {
name: domain,
},
});This matches the reference implementation pattern from the SDK docs/examples.
Observed behavior
The failure happens inside addProjectDomain() itself, before any follow-up calls or DB writes.
We confirmed this with runtime instrumentation around our flow:
- Enter provider create function
- Call
projects.addProjectDomain() - Immediate throw:
name:UnexpectedClientErrormessage:Unexpected HTTP client error: TypeError: Cannot construct a Request with a Request object that has already been used.cause.name:TypeErrorcause.message:Cannot construct a Request with a Request object that has already been used.
- No subsequent refresh/status call ran until we bypassed this SDK method
What we found
Reading the generated transport in src/lib/sdks.ts, _do() still does:
const req = await this.#hooks.beforeRequest(context, request.clone());
let response = await this.#httpClient.request(req);So this looks like a runtime-specific interaction around cloning a body-bearing Request before the actual fetch.
Workaround that fixed it for us
We replaced only this SDK call with a direct REST fetch to:
POST https://api.vercel.com/v10/projects/{idOrName}/domains?teamId=...using the same JSON body:
{ "name": "example.com" }With that workaround in place:
- create domain succeeded
- follow-up
getProjectDomain()/getDomainConfig()calls still worked through the SDK - the full feature worked again
So the issue seems isolated to this POST path / transport behavior, not to all SDK usage.