cloudflare / cloudflare/workerd
Bug: Durable Object alarm firing under `durableObjectStorage = (inMemory = void)` crashes the workerd process
- Dominant language
- C++
- Stars
- 8.7k
- Forks
- 739
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 174
Description
## 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
1. Config: one service, one DO class, `durableObjectStorage = (inMemory = void)`.
2. Worker arms an alarm: `await this.ctx.storage.setAlarm(Date.now() + 40);`
3. Alarm handler: may be completely empty (`return;`).
4. When the alarm fires, workerd exits:
```
*** Fatal uncaught kj::Exception: kj/async.c++:2202: failed: Promise callback destroyed itself.
```
## Discrimination
- With `durableObjectStorage = (localDisk = "")` 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.
Contributor guide
Research direction
Start by reproducing the supplied one-service Durable Object configuration with in-memory storage and the 40 ms setAlarm call, then compare it with the local-disk configuration. Locate the alarm and storage test layout and add coverage for an empty handler. Done means the in-memory alarm runs or produces a typed JavaScript error without terminating workerd.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, javascript
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100