workers-sdk icon indicating copy to clipboard operation
workers-sdk copied to clipboard

Calling fetch service binding requires a request object with 'host' header in vite-plugin runtime

Open niba opened this issue 5 months ago • 2 comments

What versions & operating system are you using?

vite: 6.3.5, wrangler: 4.19.2, @cloudflare/vite-plugin: ^1.5.1

Please provide a link to a minimal reproduction

No response

Describe the Bug

You need to have

  1. Two workers with a service binding between them
  2. Run the worker using vite dev with cloudflare-vite-plugin
  3. Try to call fetch using a service binding

Code in the worker

export default {
  async fetch(request, env) {
      await env.WORKER_API.fetch(request); <-- works
      await env.WORKER_API.fetch(new Request("http://internal/api")); <- doesn't work
  }
}

this code works when you try to run it using wrangler dev,

I found out that if you don't have the "host" header specified in a custom request instance then the request fails with status: 400 and text: "Bad Request".

Please provide any relevant error logs

No response

niba avatar Jun 12 '25 10:06 niba

Thanks for reporting this! Would you be able to provide a reproduction repo that demonstrates the issue?

I tried this with two basic Workers running in the Vite plugin but couldn't reproduce.

penalosa avatar Jun 12 '25 17:06 penalosa

@penalosa you can reproduce it if you go to

/packages/vite-plugin-cloudflare/playground/multi-worker/workar-a/index.ts in workers-sdk project

change existing switch fetch case to this one

case "/fetch": {
  const response = await env.WORKER_B.fetch("http://test/fetch");
  console.log("response", response); // BAD REQUEST
  const result = await response.json();
  return Response.json({
    result,
  });
}

then remove auxiliaryWorkers entry in /packages/vite-plugin-cloudflare/playground/multi-worker/vite.config.ts.

start multi-worker and try to hit http://localhost:5173/fetch

update

I forgot that I commented out auxiliaryWorkers. It does work when you have auxiliaryWorkers set. My workers don't build / run (https://github.com/cloudflare/workers-sdk/issues/8958) when I have auxiliaryWorkers defined so I don't use it.

this is probably why you couldn't reproduce it

niba avatar Jun 12 '25 18:06 niba

What you are saying is that you comment out:

			auxiliaryWorkers: [{ configPath: "./worker-b/wrangler.jsonc" }],

Which is the worker being fetched by

			case "/fetch": {
				const response = await env.WORKER_B.fetch(request);
				const result = await response.json();
				return Response.json({
					result,
				});
			}

Also:

I forgot that I commented out auxiliaryWorkers [...]

That is the exact reason why we request a minimal repro attached to issues. To test the same thing. Please think about it for the next time.

vicb avatar Jun 23 '25 13:06 vicb

You are right, sorry for not creating a repro in the first place.

@vicb The issue is still there, or at least there should be some documentation about it. There is some kind of discrepancy in how workers communicate.

You can't make fetch requests through service bindings without a host header (it can be a random value) when you run standalone workers in dev mode and a vite worker is the caller. By standalone, I mean when you run independent workers that can still see each other using dev-registry. You implemented this possibility in #8963 . You don't need to set the ⁠auxiliaryWorkers config in vite to make workers connect with each other.

Here is the repro: cf-multi-workers

So basically:

Case 1: Two workers run by wrangler dev

  • Fetch (no host header): works

  • Fetch (random host header): works

  • RPC: works

Case 2: Two workers run by one vite config using auxiliaryWorkers

  • Fetch (no host header): works

  • Fetch (random host header): works

  • RPC: works

Case 3: Two workers. One run by wrangler and another run by vite

  • Fetch (no host header): doesn't work
  • Fetch (random host header): works

  • RPC: works

Case 4: Two workers. Run by standalone vite configs

  • Fetch (no host header): doesn't work
  • Fetch (random host header): works

  • RPC: works

I don't know when ⁠auxiliaryWorkers is required because the documentation is very sparse and there is only a suggestion that you should configure it in the vite plugin. This setting causes a lot of problems when building projects. I can't make it work, and wrangler is a more mature solution, so I think normal fetch should work between them.

niba avatar Jun 24 '25 07:06 niba

@jamesopstad any thought on the issue?

vicb avatar Jun 24 '25 08:06 vicb

@niba Sorry but this is tangentially related - in your matrix you say that RPC works between 2 vite standalone workers. Did you have to do anything special to get that to work? I don't see that setup in your example repo. I'm getting the Error: Cannot access "..." as we couldn't find a local dev session for the "..." entrypoint of service "..." error everytime. Not sure if there's a trick to getting the vite processes to see each other.

zwily avatar Jul 22 '25 17:07 zwily

I confirm having the same issue between 2 workers using vite-plugin, adding the host header for now seems to work as a workaround

franciscohermida avatar Jul 24 '25 23:07 franciscohermida

Hi @niba and @franciscohermida! We have just merged the fix from #10058, which should land in the next release sometime next week. In the meantime, you can try it out using the pre-release build linked here.

edmundhung avatar Jul 25 '25 12:07 edmundhung

@zwily In my repro there are three workers: service, API, and web. The service and web workers are built with Vite and you can configure them to communicate with each other. I don’t recall any problems with RPC. Feel free to use my boilerplate to test an RPC call, and if it doesn’t work, then maybe create a new issue.

@edmundhung thanks!

niba avatar Jul 25 '25 15:07 niba