cloudflare / cloudflare/workers-sdk

🐛 BUG: `POST` with body to a Worker in local dev throws an error

Open
#6,515 5 comments 2 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
4.5k
Forks
1.5k
Avg merge
3d 8h
Merged PRs (30d)
187

Description

### Which Cloudflare product(s) does this pertain to?

Wrangler

### What version(s) of the tool(s) are you using?

wrangler@3.72.0

### What version of Node are you using?

v20.14.0

### What operating system and version are you using?

Mac OS

### Describe the Bug

### Observed behavior
Making a POST request to a durable object (or a Worker) _without_ a `content-type` header throws a weird error in local dev.

### Expected behavior
It shouldn't throw the error.

### Steps to reproduce
Full repro and instructions at https://github.com/threepointone/durable-post-error

### Please provide a link to a minimal reproduction

https://github.com/threepointone/durable-post-error

### Please provide any relevant error logs

--- 2024-08-16T18:14:52.620Z debug

🪵 Writing logs to "[redacted]/.wrangler/logs/wrangler-2024-08-16_18-14-52_550.log"
---

--- 2024-08-16T18:14:52.620Z debug
Failed to load .env file ".env": Error: ENOENT: no such file or directory, open '.env'
at Object.openSync (node:fs:573:18)
at Object.readFileSync (node:fs:452:35)
at tryLoadDotEnv ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:158723:72)
at loadDotEnv ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:158732:12)
at [redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:200869:20
at [redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:165685:16
at maybeAsyncResult ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:163906:44)
at [redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:165684:14
at [redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:163893:22
at Array.reduce () {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '.env'
}
---

--- 2024-08-16T18:14:52.627Z log

⛅️ wrangler 3.61.0 (update available 3.72.0)
-------------------------------------------------------

---

--- 2024-08-16T18:14:52.652Z warn
▲ [WARNING] Processing wrangler.toml configuration:

- "assets" fields are experimental and may change or break at any time.

---

--- 2024-08-16T18:14:52.663Z debug
Retrieving cached values for userId from node_modules/.cache/wrangler
---

--- 2024-08-16T18:14:52.663Z debug
Metrics dispatcher: Dispatching disabled - would have sent {"type":"event","name":"run dev","properties":{"local":true,"usesTypeScript":true}}.
---

--- 2024-08-16T18:14:52.664Z debug
Failed to load .env file "[redacted]/code/durable-post-error/.dev.vars": Error: ENOENT: no such file or directory, open '[redacted]/code/durable-post-error/.dev.vars'
at Object.openSync (node:fs:573:18)
at Object.readFileSync (node:fs:452:35)
at tryLoadDotEnv ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:158723:72)
at loadDotEnv ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:158732:12)
at getVarsForDev ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:198228:18)
at getBindings ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:206571:10)
at getBindingsAndAssetPaths ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:206452:20)
at getDevReactElement ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:206136:40)
at startDev ([redacted]/code/durable-post-error/node_modules/wrangler/wrangler-dist/cli.js:206200:60)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '[redacted]/code/durable-post-error/.dev.vars'
}
---

--- 2024-08-16T18:14:52.664Z log
Your worker has access to the following bindings:
- Durable Objects:
- thing: Thing
---

--- 2024-08-16T18:14:52.711Z log
⎔ Starting local server...
---

--- 2024-08-16T18:14:57.236Z debug
[InspectorProxyWorker] handleProxyControllerIncomingMessage {"type":"reloadStart"}
---

--- 2024-08-16T18:14:57.242Z debug
[InspectorProxyWorker] handleProxyControllerIncomingMessage {"type":"reloadComplete","proxyData":{"userWorkerUrl":{"protocol":"http:","hostname":"127.0.0.1","port":"57796"},"userWorkerInspectorUrl":{"protocol":"ws:","hostname":"127.0.0.1","port":"57786","pathname":"/core:user:durable-post-error"},"userWorkerInnerUrlOverrides":{"protocol":"http"},"headers":{"MF-Proxy-Shared-Secret":"47226542-9427-4b6b-a101-17378e8b9bb1"},"liveReload":false,"proxyLogsToController":false,"internalDurableObjects":[{"name":"thing","class_name":"Thing"}],"entrypointAddresses":{"Thing":{"host":"127.0.0.1","port":57797},"__INTERNAL_WRANGLER_MIDDLEWARE__":{"host":"127.0.0.1","port":57798},"default":{"host":"127.0.0.1","port":57799}}}}
---

--- 2024-08-16T18:15:00.697Z debug
workerd/util/symbolizer.c++:96: warning: Not symbolizing stack traces because $LLVM_SYMBOLIZER is not set. To symbolize stack traces, set $LLVM_SYMBOLIZER to the location of the llvm-symbolizer binary. When running tests under bazel, use `--test_env=LLVM_SYMBOLIZER=`.
workerd/jsg/util.c++:278: error: e = kj/compat/http.c++:1989: failed: expected clean; can't read more data after a previous read didn't complete
stack: 101a82afb 102f2853c 100aeb83c 1011ee3d8 100ae253c 101221a6f 101221b03; sentryErrorContext = jsgInternalError
---

--- 2024-08-16T18:15:00.748Z debug
[InspectorProxyWorker] SEND TO DEVTOOLS {"method":"Runtime.executionContextsCleared"}
---

--- 2024-08-16T18:15:00.748Z debug
[InspectorProxyWorker] NEW RUNTIME WEBSOCKET http://127.0.0.1:57786/core:user:durable-post-error
---

--- 2024-08-16T18:15:00.749Z debug
[InspectorProxyWorker] RUNTIME WEBSOCKET OPENED
---

--- 2024-08-16T18:15:00.749Z debug
[InspectorProxyWorker] SEND TO RUNTIME {"method":"Runtime.enable","id":100000001}
---

--- 2024-08-16T18:15:00.749Z debug
[InspectorProxyWorker] reconnectRuntimeWebSocket
---

--- 2024-08-16T18:15:00.750Z debug
[InspectorProxyWorker] RUNTIME INCOMING MESSAGE {
method: 'Runtime.executionContextCreated',
params: {
context: {
id: 31225345,
origin: '',
name: 'Worker',
uniqueId: '-8680546262951044072.2674101883297242401'
}
}
}
---

--- 2024-08-16T18:15:00.751Z error
✘ [ERROR] Uncaught (async) TypeError: Can't read from request stream after response has been sent.

---

--- 2024-08-16T18:15:00.751Z debug
[InspectorProxyWorker] SEND TO RUNTIME {"method":"Debugger.enable","id":100000002}
---

--- 2024-08-16T18:15:00.752Z debug
[InspectorProxyWorker] RUNTIME INCOMING MESSAGE {
method: 'Debugger.scriptParsed',
params: {
scriptId: '3',
url: 'file://[redacted]/code/durable-post-error/.wrangler/tmp/dev-ptvoTq/index.js',
startLine: 0,
startColumn: 0,
endLine: 666,
endColumn: 94,
executionContextId: 31225345,
hash: '51381fa33db140701f7856697a22a1d48c886719d6af04bd5a8893b0e8fe80b2',
isLiveEdit: false,
sourceMapURL: 'index.js.map',
hasSourceURL: true,
isModule: true,
length: 61440,
scriptLanguage: 'JavaScript',
embedderName: 'index.js'
}
}
---

--- 2024-08-16T18:15:00.752Z debug
[InspectorProxyWorker] RUNTIME INCOMING MESSAGE {
method: 'Debugger.scriptParsed',
params: {
scriptId: '4',
url: 'cloudflare:workers',
startLine: 0,
startColumn: 0,
endLine: 10,
endColumn: 0,
executionContextId: 31225345,
hash: '95b000c8168afc603c2f855cc510cdd1d9e89180fe6367ddb1665f390ef1561e',
isLiveEdit: false,
sourceMapURL: '',
hasSourceURL: false,
isModule: true,
length: 605,
scriptLanguage: 'JavaScript',
embedderName: 'cloudflare:workers'
}
}
---

--- 2024-08-16T18:15:00.752Z debug
[InspectorProxyWorker] RUNTIME INCOMING MESSAGE {
id: 100000002,
result: { debuggerId: '-207011184714484215.761388423425182187' }
}
---

--- 2024-08-16T18:15:00.753Z debug
[InspectorProxyWorker] RUNTIME INCOMING MESSAGE { id: 100000003, method: 'Network.enable', result: {} }
---

--- 2024-08-16T18:15:00.753Z debug
[InspectorProxyWorker] SEND TO RUNTIME {"method":"Network.enable","id":100000003}
---

--- 2024-08-16T18:15:00.753Z debug
[InspectorProxyWorker] RUNTIME INCOMING MESSAGE {
method: 'Runtime.exceptionThrown',
params: {
timestamp: 1723832100697,
exceptionDetails: {
exceptionId: 1,
text: 'Uncaught (async)',
lineNumber: 0,
columnNumber: -2,
url: 'undefined',
exception: [Object],
executionContextId: 31225345
}
}
}
---

--- 2024-08-16T18:15:00.753Z debug
[InspectorProxyWorker] RUNTIME INCOMING MESSAGE { id: 100000001, result: {} }
---

--- 2024-08-16T18:15:07.206Z debug
Not Implemented Error: ConfigController#teardown
---

--- 2024-08-16T18:15:07.206Z debug
ProxyController teardown
---

--- 2024-08-16T18:15:07.209Z log
⎔ Shutting down local server...
---

Contributor guide

Open the contributing guide

Research direction

Start with the linked durable-post-error minimal reproduction and Wrangler's local development entry point, focusing on POST requests to a Worker or Durable Object without a content-type header. Reproduce the uncaught TypeError shown in the logs, then verify that the same request completes without an error in local dev.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
backend, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.