Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 BUG: wrangler dev doesn't work with KV on Node.JS >= 18 #3515

Closed
ValeriyMaslenikov opened this issue Jun 23, 2023 · 3 comments
Closed
Assignees
Labels
bug Something that isn't working

Comments

@ValeriyMaslenikov
Copy link

ValeriyMaslenikov commented Jun 23, 2023

Which Cloudflare product(s) does this pertain to?

KV

What version of Wrangler are you using?

3.1.1

What operating system are you using?

MacOS (13.2.1 (22D68)), Ubuntu 22.04.2 LTS

Describe the Bug

Link to the repository with the code below.
Sample worker code I used for testing:

export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
		const testKey = 'test-key';
		console.log(await env.wrangler_troubleshooting.put(testKey, 'test-value'));
		console.log(await env.wrangler_troubleshooting.get(testKey));

		return new Response(JSON.stringify({ Hello: 'World!' }));
	},
};

wrangler.toml:

name = "troubleshoot"
main = "src/worker.ts"
compatibility_date = "2023-06-23"

kv_namespaces = [
    { binding = "wrangler_troubleshooting", id = "...", preview_id = "..." },
]

[dev]
ip = "localhost"
port = 8089
local_protocol = "http"

Node.JS 16

Here it's the behavior on Node.JS 16. To make it work I:

  1. Make clear installation of Node.JS: nvm install 16.20.1
  2. Just in case remove old node_modules: rm -rf ./node_modules, remove npm cache: npm cache clean --force
  3. Install deps: npm i
  4. run npx wrangler dev --log-level=debug

Application starts and I can see the in the logs the test-value:

[mf:inf] POST /api 200 OK (15ms)
workerd/io/worker.c++:1703: info: uncaught exception; source = Uncaught (async); exception = TypeError: Can't read from request stream after response has been sent.
test-value

Node.JS 18

Doing the same stuff as for 16 and I'm testing on 18.16.1 (on both MacOS and Ubuntu).
Output of npx wrangler dev --log-level=debug after making the first call

/home# npx wrangler dev --log-level=debug
 ⛅️ wrangler 3.1.1
------------------
wrangler dev now uses local mode by default, powered by 🔥 Miniflare and 👷 workerd.
To run an edge preview session for your Worker, use wrangler dev --remote
▲ [WARNING] Setting upstream-protocol to http is not currently implemented.

  If this is required in your project, please add your use case to the following issue:
  https://github.com/cloudflare/workers-sdk/issues/583.


Metrics dispatcher: Dispatching disabled - would have sent {"type":"event","name":"run dev","properties":{"local":true,"usesTypeScript":true}}.
Failed to load .env file "/home/.dev.vars": Error: ENOENT: no such file or directory, open '/home/.dev.vars'
    at Object.openSync (node:fs:601:3)
    at Object.readFileSync (node:fs:469:35)
    at tryLoadDotEnv (/home/node_modules/wrangler/wrangler-dist/cli.js:123917:72)
    at loadDotEnv (/home/node_modules/wrangler/wrangler-dist/cli.js:123926:12)
    at getVarsForDev (/home/node_modules/wrangler/wrangler-dist/cli.js:148837:18)
    at getBindings (/home/node_modules/wrangler/wrangler-dist/cli.js:149743:10)
    at getBindingsAndAssetPaths (/home/node_modules/wrangler/wrangler-dist/cli.js:149702:20)
    at getDevReactElement (/home/node_modules/wrangler/wrangler-dist/cli.js:149388:40)
    at startDev (/home/node_modules/wrangler/wrangler-dist/cli.js:149449:60)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: '/home/.dev.vars'
}
Your worker has access to the following bindings:
- KV Namespaces:
  - wrangler_troubleshooting: 79da6370722e4367af935dc274aa0c73
⎔ Starting local server...
[mf:wrn] The latest compatibility date supported by the installed Cloudflare Workers Runtime is "2023-05-18",
but you've requested "2023-06-23". Falling back to "2023-05-18"...
workerd/server/server.c++:2431: info: Inspector is listening
[mf:inf] Ready on http://localhost:8089/
workerd/server/server.c++:1018: info: Inspector client attaching [core:user:troubleshoot]
workerd/jsg/util.c++:278: info: exception = kj/async-io-unix.c++:1526: disconnected: connect(): Connection refused
stack: /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e97086 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e97509 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e8bee0 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e8c6b0 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e7f140 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e81220 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1ea15a0 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1ea1a90 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1ea10f0 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e6d120 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e6d120 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@19c9ba0 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@164e440
workerd/jsg/util.c++:278: info: exception = kj/async.c++:212: disconnected: operation canceled
stack: /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e6a45c /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e4f4b2 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@17ec95e /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e4f90d /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1987c23 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e4f55f /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e50ab8 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e51301 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e57b34 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e4dcc7 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@150bfb6 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1510d47 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1510ac4 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1510aac /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2ec38d8 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e47380 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@2e73560 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@15342d0 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@1741580 /home/node_modules/@cloudflare/workerd-linux-64/bin/workerd@18c2440
workerd/io/worker.c++:1703: info: uncaught exception; source = Uncaught (in promise); exception = Error: Network connection lost.
workerd/io/worker.c++:1703: info: uncaught exception; source = Uncaught (async); exception = Error: Network connection lost.

And the response to this HTTP call is:

curl localhost:8089/api
{"name":"Error","message":"Network connection lost.","stack":"Error: Network connection lost."}

Severity of the problem

As far as we're using Queues, which are not supported on Node.JS 16, we can't use this version for local development:

Error reloading local server: QueuesError [ERR_V8_UNSUPPORTED]: The version of V8 bundled with this version of Node.js does not support Queues. Please upgrade to the latest Node.js LTS release.
@ValeriyMaslenikov ValeriyMaslenikov added the bug Something that isn't working label Jun 23, 2023
@github-project-automation github-project-automation bot moved this to Untriaged in workers-sdk Jun 23, 2023
@mrbbot
Copy link
Contributor

mrbbot commented Jun 23, 2023

Hey! 👋 Thanks for reporting this, and including a reproduction! 😃 I'm able to reproduce this with Wrangler, but not using Miniflare directly, which is very interesting. Will try dig into this more now. 👍

@mrbbot mrbbot moved this from Untriaged to Backlog in workers-sdk Jun 23, 2023
@mrbbot mrbbot self-assigned this Jun 23, 2023
@mrbbot
Copy link
Contributor

mrbbot commented Jun 23, 2023

Seems like removing ip = "localhost" from wrangler.toml fixes this issue. I suspect this is related to IPv4/IPv6 DNS resolution changes in Node 17: nodejs/node#39987. Very likely a bug on our side, this should unblock you though.

@ValeriyMaslenikov
Copy link
Author

@mrbbot , thanks a lot for the extra fast response, it's a great feeling coming back from lunch with ready work-around.
I verified and removing ip from wrangler.toml fixes the problem and now my worker has access to KV.

mrbbot added a commit to cloudflare/miniflare that referenced this issue Jun 27, 2023
Miniflare starts its loopback server on the same host as the
`workerd` server, so it's accessible on all the same addresses as the
runtime. This allows the loopback server to be the target for the
live reload web socket. This means if the `host: "localhost"` option
is set, we start a Node `http` server with `localhost` as the
hostname. Node will perform a DNS lookup to work out which IP address
and interface to listen on, but will only listen on the first entry.
In Node 17+, this will be the IPv6 interface. Unfortunately, we
previously hardcoded the loopback address as the IPv4 loopback,
meaning `workerd` was unable to connect. This change switches to
using `localhost`, which `workerd` will resolve to either IPv4 or v6.

Closes cloudflare/workers-sdk#3515
mrbbot added a commit to cloudflare/miniflare that referenced this issue Jun 27, 2023
Miniflare starts its loopback server on the same host as the
`workerd` server, so it's accessible on all the same addresses as the
runtime. This allows the loopback server to be the target for the
live reload web socket. This means if the `host: "localhost"` option
is set, we start a Node `http` server with `localhost` as the
hostname. Node will perform a DNS lookup to work out which IP address
and interface to listen on, but will only listen on the first entry.
In Node 17+, this will be the IPv6 interface. Unfortunately, we
previously hardcoded the loopback address as the IPv4 loopback,
meaning `workerd` was unable to connect. This change switches to
using `localhost`, which `workerd` will resolve to either IPv4 or v6.

Closes cloudflare/workers-sdk#3515
@penalosa penalosa closed this as completed Jul 6, 2023
@github-project-automation github-project-automation bot moved this from Backlog to Done in workers-sdk Jul 6, 2023
mrbbot added a commit that referenced this issue Oct 31, 2023
Miniflare starts its loopback server on the same host as the
`workerd` server, so it's accessible on all the same addresses as the
runtime. This allows the loopback server to be the target for the
live reload web socket. This means if the `host: "localhost"` option
is set, we start a Node `http` server with `localhost` as the
hostname. Node will perform a DNS lookup to work out which IP address
and interface to listen on, but will only listen on the first entry.
In Node 17+, this will be the IPv6 interface. Unfortunately, we
previously hardcoded the loopback address as the IPv4 loopback,
meaning `workerd` was unable to connect. This change switches to
using `localhost`, which `workerd` will resolve to either IPv4 or v6.

Closes #3515
mrbbot added a commit that referenced this issue Nov 1, 2023
Miniflare starts its loopback server on the same host as the
`workerd` server, so it's accessible on all the same addresses as the
runtime. This allows the loopback server to be the target for the
live reload web socket. This means if the `host: "localhost"` option
is set, we start a Node `http` server with `localhost` as the
hostname. Node will perform a DNS lookup to work out which IP address
and interface to listen on, but will only listen on the first entry.
In Node 17+, this will be the IPv6 interface. Unfortunately, we
previously hardcoded the loopback address as the IPv4 loopback,
meaning `workerd` was unable to connect. This change switches to
using `localhost`, which `workerd` will resolve to either IPv4 or v6.

Closes #3515
mrbbot added a commit that referenced this issue Nov 1, 2023
Miniflare starts its loopback server on the same host as the
`workerd` server, so it's accessible on all the same addresses as the
runtime. This allows the loopback server to be the target for the
live reload web socket. This means if the `host: "localhost"` option
is set, we start a Node `http` server with `localhost` as the
hostname. Node will perform a DNS lookup to work out which IP address
and interface to listen on, but will only listen on the first entry.
In Node 17+, this will be the IPv6 interface. Unfortunately, we
previously hardcoded the loopback address as the IPv4 loopback,
meaning `workerd` was unable to connect. This change switches to
using `localhost`, which `workerd` will resolve to either IPv4 or v6.

Closes #3515
mrbbot added a commit that referenced this issue Nov 1, 2023
Miniflare starts its loopback server on the same host as the
`workerd` server, so it's accessible on all the same addresses as the
runtime. This allows the loopback server to be the target for the
live reload web socket. This means if the `host: "localhost"` option
is set, we start a Node `http` server with `localhost` as the
hostname. Node will perform a DNS lookup to work out which IP address
and interface to listen on, but will only listen on the first entry.
In Node 17+, this will be the IPv6 interface. Unfortunately, we
previously hardcoded the loopback address as the IPv4 loopback,
meaning `workerd` was unable to connect. This change switches to
using `localhost`, which `workerd` will resolve to either IPv4 or v6.

Closes #3515
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something that isn't working
Projects
None yet
Development

No branches or pull requests

3 participants