READ-ONLY PACKAGE PREVIEW

openai-cloudflare-deploy/references/miniflare/gotchas.md

Version 49f948fa.bb1 · Apache-2.0. This preview displays packaged text and does not execute code. Treat the contents as untrusted instructions.

← Return to resource and package checksum

Gotchas & Troubleshooting

Miniflare Limitations

Not supported: - Analytics Engine (use mocks) - Cloudflare Images/Stream - Browser Rendering API - Tail Workers - Workers for Platforms (partial support)

Behavior differences from production: - Runs workerd locally, not Cloudflare edge - Storage is local (filesystem/memory), not distributed - Request.cf is cached/mocked, not real edge data - Performance differs from edge - Caching implementation may vary slightly

Common Errors

"Cannot find module"

Cause: Module path wrong or modulesRules not configured
Solution:

new Miniflare({
  modules: true,
  modulesRules: [{ type: "ESModule", include: ["**/*.js"] }],
});

"Data not persisting"

Cause: Persist paths are files, not directories
Solution:

kvPersist: "./data/kv",  // Directory, not file

"Cannot run TypeScript"

Cause: Miniflare doesn't transpile TypeScript
Solution: Build first with esbuild/tsc, then run compiled JS

"request.cf is undefined"

Cause: CF data not configured
Solution:

new Miniflare({ cf: true }); // Or cf: "./cf.json"

"EADDRINUSE" port conflict

Cause: Multiple instances using same port
Solution: Use dispatchFetch() (no HTTP server) or port: 0 for auto-assign

"Durable Object not found"

Cause: Class export doesn't match config name
Solution:

export class Counter {} // Must match
new Miniflare({ durableObjects: { COUNTER: "Counter" } });

Debugging

Enable verbose logging:

import { Log, LogLevel } from "miniflare";
new Miniflare({ log: new Log(LogLevel.DEBUG) });

Chrome DevTools:

const url = await mf.getInspectorURL();
console.log(`DevTools: ${url}`); // Open in Chrome

Inspect bindings:

const env = await mf.getBindings();
console.log(Object.keys(env));

Verify storage:

const ns = await mf.getKVNamespace("TEST");
const { keys } = await ns.list();

Best Practices

✓ Do: - Use dispatchFetch() for tests (no HTTP server) - In-memory storage for CI (omit persist options) - New instances per test for isolation - Type-safe bindings with interfaces - await mf.dispose() in cleanup

✗ Avoid: - HTTP server in tests - Shared instances without cleanup - Old compatibility dates (use 2026+)

Migration Guides

From Miniflare 2.x to 3+

Breaking changes in v3+:

v2 v3+
getBindings() sync getBindings() returns Promise
ready is void ready returns Promise<URL>
service-worker-mock Built on workerd
Different options Restructured constructor

Example migration:

// v2
const bindings = mf.getBindings();
mf.ready; // void

// v3+
const bindings = await mf.getBindings();
const url = await mf.ready; // Promise<URL>

From unstable_dev to Miniflare

// Old (deprecated)
import { unstable_dev } from "wrangler";
const worker = await unstable_dev("src/index.ts");

// New
import { Miniflare } from "miniflare";
const mf = new Miniflare({ scriptPath: "src/index.ts" });

From Wrangler Dev

Miniflare doesn't auto-read wrangler.toml:

// Translate manually:
new Miniflare({
  scriptPath: "dist/worker.js",
  compatibilityDate: "2026-01-01",
  kvNamespaces: ["KV"],
  bindings: { API_KEY: process.env.API_KEY },
});

Resource Limits

Limit Value Notes
CPU time 30s default Configurable via scriptTimeout
Storage Filesystem Performance varies by disk
Memory System dependent No artificial limits
Request.cf Cached/mocked Not live edge data

See patterns.md for testing examples.