cloudflare

compatibility dates

why wasm breaks silently and how compatibility_date fixes it

compatibility dates

cloudflare workers pin runtime behavior to a specific date. javascript apis added after your compatibility_date are unavailable — failures are often silent.

why some apis are gated

workers run in v8 isolates where deterministic execution matters. WeakRef and FinalizationRegistry let code observe garbage collection — a fundamentally nondeterministic process. cloudflare disabled both by default to prevent gc-dependent behavior in a serverless model where isolation and consistency are critical.

the enable_weak_ref flag opts into the nondeterminism tradeoff. enables both apis together — WeakRef alone is safer but the two are almost always used as a pair.

feature minimum date flag
WeakRef 2025-05-05 enable_weak_ref
FinalizationRegistry 2025-05-05 enable_weak_ref

why wasm runtimes need them

wasm modules that bridge to javascript need to track host object lifecycles. when a js-side wrapper gets garbage collected, the wasm side needs to clean up the corresponding resource. FinalizationRegistry handles this — register a callback when the wrapper is created, clean up when it's collected.

runtimes that depend on this:

  • teavm (elk wasm) — jso interop, weak reference tracking, string finalization
  • tinygo — wasi stubs with host object bridging
  • any wasm module using weak reference tracking for js/wasm boundary management

without the flag, registrations silently fail. the module loads, init appears to succeed, but every function call throws.

issue i had

the tools worker had compatibility_date = "2024-12-01". go wasm loaded without error but goEncrypt() / goDecrypt() threw — init silently failed because the runtime lacked FinalizationRegistry. same failure mode affected elk wasm for architecture diagram layouts.

no deploy-time warning. no init-time error. failure only at call time.

# wrangler.toml — before
compatibility_date = "2024-12-01"

# after
compatibility_date = "2025-06-01"

alternatively, pin the flag without bumping the full date:

compatibility_flags = ["enable_weak_ref"]