In wrangler dev, calling ctx.storage.setAlarm() from inside a Durable Object facet of a SQLite-backed DO appears to succeed, then asynchronously breaks the whole actor with:
Error: alarms are not yet implemented for SQLite-backed Durable Objects
The error does not throw from the setAlarm() call. It surfaces as the rejection of an unrelated in-flight RPC into the facet, with no facet-side stack frames.
Minimal repro: https://github.com/firtoz/facet-alarm-repro
Repro
git clone https://github.com/firtoz/facet-alarm-repro
cd facet-alarm-repro
npm install
npx wrangler dev
curl 'http://127.0.0.1:8799/repro'
curl 'http://127.0.0.1:8799/repro?facetAlarm=off'
Expected:
/repro should either complete, or setAlarm() inside the facet should throw synchronously with a clear "facet alarms are unsupported" error.
/repro?facetAlarm=off should complete.
Actual:
/repro returns ok: false; the host -> facet RPC rejects with alarms are not yet implemented for SQLite-backed Durable Objects.
/repro?facetAlarm=off completes normally.
Important detail
The facet's setAlarm() call logs success before the actor breaks:
{"tag":"leaf:hold:start","ms":4000,"setAlarm":true}
{"tag":"leaf:setAlarm:ok"}
So userland cannot catch this at the alarm call site.
Environment
- Reproduced on wrangler 4.85.0 through 4.100.0.
compatibility_date: 2026-04-24
- SQLite-backed DO via
new_sqlite_classes
- Facet spawned with
ctx.facets.get(name, () => ({ class: ctx.exports.Leaf }))
- Linux x64
Likely source
From workerd source:
src/workerd/server/server.c++: facet actors (parent != kj::none) get ActorSqlite::Hooks::getDefaultHooks() with a TODO: Support alarms in facets, somehow.
src/workerd/io/actor-sqlite.c++: default Hooks::scheduleRun() throws alarms are not yet implemented for SQLite-backed Durable Objects.
It looks like the output-gate commit path calls scheduleRun() after the JS setAlarm() call has already resolved, breaking the actor asynchronously.
Why this matters
Frameworks like agents / Think use alarms for keep-alive and scheduling. If such framework code runs inside a facet, the actor can be broken by a successful-looking setAlarm() call, and the error appears elsewhere as an unrelated RPC failure.
Suggested fix
Either:
- Support facet alarms in local workerd; or
- Make
setAlarm() on facet storage throw synchronously at the call site in local dev, with an error that explicitly says alarms are unsupported in facets.
In
wrangler dev, callingctx.storage.setAlarm()from inside a Durable Object facet of a SQLite-backed DO appears to succeed, then asynchronously breaks the whole actor with:The error does not throw from the
setAlarm()call. It surfaces as the rejection of an unrelated in-flight RPC into the facet, with no facet-side stack frames.Minimal repro: https://github.com/firtoz/facet-alarm-repro
Repro
Expected:
/reproshould either complete, orsetAlarm()inside the facet should throw synchronously with a clear "facet alarms are unsupported" error./repro?facetAlarm=offshould complete.Actual:
/reproreturnsok: false; the host -> facet RPC rejects withalarms are not yet implemented for SQLite-backed Durable Objects./repro?facetAlarm=offcompletes normally.Important detail
The facet's
setAlarm()call logs success before the actor breaks:{"tag":"leaf:hold:start","ms":4000,"setAlarm":true} {"tag":"leaf:setAlarm:ok"}So userland cannot catch this at the alarm call site.
Environment
compatibility_date: 2026-04-24new_sqlite_classesctx.facets.get(name, () => ({ class: ctx.exports.Leaf }))Likely source
From workerd source:
src/workerd/server/server.c++: facet actors (parent != kj::none) getActorSqlite::Hooks::getDefaultHooks()with a TODO:Support alarms in facets, somehow.src/workerd/io/actor-sqlite.c++: defaultHooks::scheduleRun()throwsalarms are not yet implemented for SQLite-backed Durable Objects.It looks like the output-gate commit path calls
scheduleRun()after the JSsetAlarm()call has already resolved, breaking the actor asynchronously.Why this matters
Frameworks like
agents/ Think use alarms for keep-alive and scheduling. If such framework code runs inside a facet, the actor can be broken by a successful-lookingsetAlarm()call, and the error appears elsewhere as an unrelated RPC failure.Suggested fix
Either:
setAlarm()on facet storage throw synchronously at the call site in local dev, with an error that explicitly says alarms are unsupported in facets.