Summary
Any Durable Object alarm that FIRES while the worker is configured with
durableObjectStorage = (inMemory = void) terminates the entire workerd
process with an uncaught KJ exception. The alarm handler body is irrelevant
(an empty handler crashes identically).
Local-dev configuration surface; production DOs are disk-backed.
Environment
- workerd 1.20260826.1, macOS arm64 (release build) and linux arm64 (ASAN build) — both reproduce identically
compatibilityDate: 2026-08-26 and 2024-09-23 (both reproduce)
Repro
- Config: one service, one DO class,
durableObjectStorage = (inMemory = void).
- Worker arms an alarm:
await this.ctx.storage.setAlarm(Date.now() + 40);
- Alarm handler: may be completely empty (
return;).
- When the alarm fires, workerd exits:
*** Fatal uncaught kj::Exception: kj/async.c++:2202: failed: Promise callback destroyed itself.
Discrimination
- With
durableObjectStorage = (localDisk = "<writable disk service>") the same alarm fires and completes cleanly.
deleteAlarm() before the scheduled time does not crash.
ctx.abort() inside the handler does not crash (the DO resets instead); with the default options no retry was observed post-reset.
Expected
An alarm firing under in-memory storage should behave like the disk-backed
path (handler runs or a well-typed JS error surfaces), never abort the whole
process.
Notes
Happy to send the exact single-file config + worker used, or open a PR with a repro test if pointed at the right test layout.
Summary
Any Durable Object alarm that FIRES while the worker is configured with
durableObjectStorage = (inMemory = void)terminates the entire workerdprocess with an uncaught KJ exception. The alarm handler body is irrelevant
(an empty handler crashes identically).
Local-dev configuration surface; production DOs are disk-backed.
Environment
compatibilityDate: 2026-08-26 and 2024-09-23 (both reproduce)Repro
durableObjectStorage = (inMemory = void).await this.ctx.storage.setAlarm(Date.now() + 40);return;).Discrimination
durableObjectStorage = (localDisk = "<writable disk service>")the same alarm fires and completes cleanly.deleteAlarm()before the scheduled time does not crash.ctx.abort()inside the handler does not crash (the DO resets instead); with the default options no retry was observed post-reset.Expected
An alarm firing under in-memory storage should behave like the disk-backed
path (handler runs or a well-typed JS error surfaces), never abort the whole
process.
Notes
Happy to send the exact single-file config + worker used, or open a PR with a repro test if pointed at the right test layout.