Astro Info
Astro v6.2.1
Vite v7.3.2
Node v22.22.2
System Linux (x64)
Package Manager npm
Output static
Adapter none
Integrations none
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
When an existing session has data in backing storage and the client holds a valid session cookie, calling session.delete(key) as the very first mutation in a request (no prior get, set, has, keys, etc.) silently skips
persisting the deletion. The backing store is unchanged after the request ends, so the next request still sees the supposedly-deleted key.
Root cause (packages/astro/src/core/session/runtime.ts)
delete() (line 156) does this.#data?.delete(key) — a no-op when #data is undefined — adds the key to #toDelete, and sets #dirty = true. It does not initialize #data (unlike set() which does this.#data ??= new Map()).
[PERSIST_SYMBOL]() (line 272) gates the entire save block on:
if (this.#dirty && this.#data) {
Because a delete-only request never touches #data, it stays undefined.
The condition is false, setItem is never called, and #toDelete is never applied to storage. The previous blob in the backing store is left intact.
Why this matters
Logout and cleanup flows routinely remove session keys without reading them first. Those deletions are silently dropped while the session ID and cookie remain valid, so the next request can still see stale credentials, tokens, or
feature flags.
What's the expected result?
After session.delete('key') and normal request teardown (persist), the backing store must reflect the deletion. A new AstroSession instance with the same session ID must not return the deleted key when loading from storage.
Link to Minimal Reproducible Example
https://github.com/Hunnyboy1217/session-delete-repro
Participation
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
When an existing session has data in backing storage and the client holds a valid session cookie, calling
session.delete(key)as the very first mutation in a request (no priorget,set,has,keys, etc.) silently skipspersisting the deletion. The backing store is unchanged after the request ends, so the next request still sees the supposedly-deleted key.
Root cause (
packages/astro/src/core/session/runtime.ts)delete()(line 156) doesthis.#data?.delete(key)— a no-op when#dataisundefined— adds the key to#toDelete, and sets#dirty = true. It does not initialize#data(unlikeset()which doesthis.#data ??= new Map()).[PERSIST_SYMBOL]()(line 272) gates the entire save block on:Because a delete-only request never touches
#data, it staysundefined.The condition is
false,setItemis never called, and#toDeleteis never applied to storage. The previous blob in the backing store is left intact.Why this matters
Logout and cleanup flows routinely remove session keys without reading them first. Those deletions are silently dropped while the session ID and cookie remain valid, so the next request can still see stale credentials, tokens, or
feature flags.
What's the expected result?
After
session.delete('key')and normal request teardown (persist), the backing store must reflect the deletion. A newAstroSessioninstance with the same session ID must not return the deleted key when loading from storage.Link to Minimal Reproducible Example
https://github.com/Hunnyboy1217/session-delete-repro
Participation