From fabe86b3de71f82d1548fba54f8f6d7122518cd5 Mon Sep 17 00:00:00 2001 From: codebit0 <34156842+codebit0@users.noreply.github.com> Date: Sun, 21 Jun 2026 09:36:28 +0900 Subject: [PATCH] fix(cron): invert stateless gate to match UI label (#1139) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cron job handler reset the session when stateless=false and skipped reset when stateless=true — the opposite of what every UI locale labels the field (en/ko/zh/vi all describe stateless as "each run starts fresh without loading previous messages"). The buggy gate caused stateless=true crons to silently accumulate session history across every execution, leading to context bloat and increasing the chance of LLMs short-circuiting tool calls in favor of replaying prior assistant turns. One affected daily ETL cron grew to 38 messages over 18 days before the regression was noticed. Fix: gate the Reset on `if job.Stateless` so the runtime matches the UI contract. No DB migration is required — existing values were set by users based on the UI label, so they already encode the intended behavior. Co-authored-by: Claude Opus 4.7 (1M context) --- cmd/gateway_cron.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cmd/gateway_cron.go b/cmd/gateway_cron.go index 3b2b10d9..0b64444b 100644 --- a/cmd/gateway_cron.go +++ b/cmd/gateway_cron.go @@ -88,11 +88,14 @@ func makeCronJobHandler(sched *scheduler.Scheduler, msgBus *bus.MessageBus, cfg cronCtx = store.WithCredentialUserID(cronCtx, job.Payload.CredentialUserID) } - // Reset session before each cron run to prevent tool errors from previous - // runs from polluting the context and blocking future executions (#294). - // Save() persists the empty session to DB so stale data won't reload after restart. - // Stateless jobs skip this — they intentionally carry no session history. - if !job.Stateless { + // Stateless jobs explicitly reset their session before each run — they + // carry no history between executions, matching the "Stateless" UI label + // and statelessHelp ("each run starts fresh without loading previous + // messages"). Stateful (non-stateless) jobs keep prior turns to enable + // multi-run dialog. + // Save() persists the empty session to DB so stale data won't reload + // after restart (#294). + if job.Stateless { sessionMgr.Reset(cronCtx, sessionKey) sessionMgr.Save(cronCtx, sessionKey) }