miniflare failed with 'ERR_RUNTIME_FAILURE' and no stack trace
Fixes miniflare crashing with ERR_RUNTIME_FAILURE and no usable stack. Use when local dev dies with this opaque error. Not for workerd errors with proper stacks, wrangler dev startup failures, or deployed-worker crashes.
TL;DR
Miniflare wraps workerd crashes in ERRRUNTIMEFAILURE, and when the underlying error has no stack (startup failures, config errors, native crashes), you get the wrapper with nothing inside. Get the real error by running workerd directly with verbose logging, fixing the underlying startup problem, and only then returning to miniflare.
The query
miniflare failed with 'ERR_RUNTIME_FAILURE' and no stack traceUse this when
wrangler devor miniflare exits with ERRRUNTIMEFAILURE.- There is no stack trace, only the error code.
- The same code deploys fine (or fails differently when deployed).
Not for
- workerd runtime errors WITH stacks (debug those directly).
- 'workerd failed to start, no error output' (broader startup problem).
- Errors that reproduce identically on deployed workers (not miniflare-specific).
Steps
Step 1: Increase log verbosity
npx wrangler dev --log-level debugExpected result: the debug output often contains the underlying workerd message that the terse mode swallowed.
Step 2: Isolate with a minimal entry
Temporarily replace the entry with a hello-world worker and restart dev.
Expected result: if the minimal worker runs, the crash is in your code or config, not the toolchain. Bisect by re-adding pieces.
Step 3: Check the usual silent killers
Invalid wrangler.toml sections, a main pointing at a missing file, bindings referencing nonexistent namespaces, and compatibility date problems all produce stackless startup failures.
Expected result: one of these is misconfigured. Fix it and the runtime starts.
Step 4: Run workerd directly for the raw error
If wrangler still hides the cause, invoke the underlying runtime with explicit config to see the uncaught startup error.
Expected result: the raw workerd output names the real failure (bad import, bad binding, bad flag).
Step 5: Pin versions after fixing
Expected result: wrangler, workerd, and miniflare versions are pinned in the project so a toolchain update cannot reintroduce the opaque failure silently.
Why it happens
Local dev stacks three layers: wrangler, miniflare, workerd. Errors from the bottom layer get re-wrapped at each level, and stackless errors (startup crashes, config rejections) lose their context in the wrapping. The top-level message is accurate ('the runtime failed') but useless for debugging.
Edge cases
- Node version mismatches cause native-module-flavored ERRRUNTIMEFAILURE. Match the project's documented Node version.
- Port conflicts can masquerade as runtime failures when the error handling is poor. Check for 'port in use' separately.
- Vitest-based worker tests use miniflare under the hood; the same opaque error appears there with even less context.
- If the minimal worker ALSO fails, reinstall node_modules and the wrangler toolchain before debugging further.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_kRJWZ1saG3zL3FNBMLFiAw