Skip to content

projects.addProjectDomain throws UnexpectedClientError with reused Request in Next.js server runtime #238

@mgm1313

Description

@mgm1313

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:

  1. Enter provider create function
  2. Call projects.addProjectDomain()
  3. Immediate throw:
    • name: UnexpectedClientError
    • message: Unexpected HTTP client error: TypeError: Cannot construct a Request with a Request object that has already been used.
    • cause.name: TypeError
    • cause.message: Cannot construct a Request with a Request object that has already been used.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions