[Bug]: Uncaught BadResource: Bad resource ID crashes the entire Deno runtime process when a client aborts a function request mid-flight
What's the bug?
Where: functions/server.ts:237 (confirmed against current main)
Real stack trace (captured on self-hosted, deno-runtime@sha256:43d086b5e885307e513879fe8fd307cb3dd1a388ec271fc717f06d767da49cbc):
error: Uncaught (in promise) BadResource: Bad resource ID
const body = request.body ? await request.text() : null;
^
at readableStreamCollectIntoUint8Array (ext:deno_web/06_streams.js:1061:23)
at InnerBody.consume (ext:deno_fetch/22_body.js:162:14)
at consumeBody (ext:deno_fetch/22_body.js:254:34)
at Request.text (ext:deno_fetch/22_body.js:350:16)
at file:///app/server.ts:239:47
at new Promise (<anonymous>)
at executeInWorker (file:///app/server.ts:183:10)
at eventLoopTick (ext:core/01_core.js:175:7)
at async file:///app/server.ts:290:24Impact: the rejection is never caught (Uncaught (in promise)), so it crashes the entire Deno runtime process — not just that one invocation — affecting any other edge function in flight at that moment, not just the one that triggered it. The process auto-restarts (~300-400ms), and any request that lands in that window gets connection-refused (surfaced as a 502 through a reverse proxy in front of it).
Suggested fix: wrap the body read in a try/catch and return a handled response (or simply abort that invocation) instead of leaving it as an unhandled rejection — same spirit as the worker.onerror handler a few lines above, which already handles worker errors without taking down the whole process.
Related but distinct:
- #1510 — a different bug in the same
executeInWorker()/server.ts, useful precedent that InsForge accepts and fixes well-documented reports here. - denoland/deno#15442 — the underlying
BadResource: Bad resource IDpattern is a known, still-open Deno core bug. The root cause isn't unique to InsForge, but leaving it uncaught and crashing the whole runtime process is.
How to reproduce
- Client does a fetch() with an AbortSignal against POST /functions/.
- Client cancels the connection before the server finishes reading the body (e.g. a React component unmounts and calls AbortController.abort() in a useEffect cleanup — the standard deduplication pattern used under React.StrictMode's double-invoked effects).
- executeInWorker() in server.ts reaches await request.text() on a request whose underlying stream is already closed client-side.
- request.text() rejects with BadResource: Bad resource ID; nothing catches it; the process crashes.
Environment (optional)
ghcr.io/insforge/deno-runtime@sha256:43d086b5e885307e513879fe8fd307cb3dd1a388ec271fc717f06d767da49cbc(built 2026-05-28)ghcr.io/insforge/insforge-oss:v2.0.3- Confirmed the exact same unguarded line still exists on
maintoday
Source: InsForge/InsForge