sessions.reset ID Reuse & Gateway RAM ExhaustionGenerated by ARK (Agent Reliability Kit) · 2026-07-27 · Target: OpenClaw 2026.7.2-beta.4, Windows 11 build 26200 · Original issue
Two independently actionable regressions collide in one incident:
| # | Symptom | Severity | Class |
|---|---|---|---|
| F-1 | Repeated sessions.catalog.list / sessions.files.list scans grow RAM until Gateway crash | CRITICAL | Unbounded scan / missing cache |
| F-2 | sessions.reset retires generation but reuses session ID → next turn self-rejects ("no longer current") | CRITICAL | Generation/ID mismatch |
| F-3 | No back-pressure between UI polling rate and store scan cost | MEDIUM | Missing rate limiting |
Every Control-UI tick issues a fresh catalog/file listing. Each call is a full scan over the Codex session store. With a large store, scans overlap — a new scan starts before the previous finishes. Result: monotonic CPU/RAM growth → Gateway-wide unresponsiveness → OOM crash. Overlaps with #113171 / #110796 but is independently fixable.
sessions.reset invalidates the current Codex generation but hands the client back the same session ID. The next turn presents the old generation token bound to that ID and is rejected:
Codex session generation is no longer current: <session-id>
This is a classic idempotency-boundary bug: the reset operation has a side effect (generation bump) that is not reflected in the handle the caller keeps using.
// pseudo-patch: sessions catalog service
const cache = new TTLCache({ ttl: 2000 }); // 2s TTL
let inflight = null;
async function listCatalog() {
if (cache.has('catalog')) return cache.get('catalog');
if (inflight) return inflight; // coalesce concurrent callers
inflight = scanStore().then(r => {
cache.set('catalog', r); inflight = null; return r;
});
return inflight;
}
// sessions.reset should return the NEW binding
function reset(sessionId) {
retireGeneration(sessionId);
const next = mintGeneration(sessionId); // new generation counter
return { sessionId, generation: next }; // client rebinds explicitly
}
// Control UI: debounce catalog refresh to ≥2s, pause when tab hidden
const refresh = debounce(fetchCatalog, 2000, { leading: true });
sessions.reset, start a new session instead of continuing the old handle (avoids F-2 entirely)All three findings belong to failure classes ARK guards against in agent systems:
| Finding | Failure class | ARK guard |
|---|---|---|
| F-1 | Unbounded repeated work | IdempotencyGuard — dedupe identical in-flight calls |
| F-2 | Stale handle after state change | OutputValidator — verify handles/generations after mutation |
| F-3 | Retry/poll storm | CircuitBreaker — back off when latency degrades |
pip install ark-trust # Python
npm install @feilunxitong/arkit # TypeScript
After this report was published, upstream work independently confirmed both critical findings — with merged code, not opinions:
| Finding | Upstream confirmation |
|---|---|
| F-2 (reset reuses the retired ID) | PR #114056 resolves the same-ID reset path while retaining deletion fences |
| F-1 (unbounded full rescans) | PR #114401 + PR #114478 replace sessions.files.list full rescans with incremental touched-file folding, bounded LRU state, per-session singleflight, and inter-page yields; PR #114358 removes repeated entry-store enumeration within one catalog request |
| Remaining seam | Cross-request sessions.catalog.list provider coalescing — PR #114160 is the narrower candidate (per-provider in-flight sharing), pending exact-head validation |
Credit: PollyBot13's current-main update mapped these merged fixes back to the findings above. The fix shapes match this report's recommendations (coalesce + cache for F-1; explicit generation-handle rebind for F-2).
Idempotency guards · retry policy · logging — free 30-second check.
Run the free ARK diagnostic →