diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c9c649d7f9..d38c10cf6d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Docs: https://docs.openclaw.ai - Agents/embedded logs: add structured, sanitized lifecycle and failover observation events so overload and provider failures are easier to tail and filter. (#41336) thanks @altaywtf. - iOS/gateway foreground recovery: reconnect immediately on foreground return after stale background sockets are torn down, so the app no longer stays disconnected until a later wake path happens. (#41384) Thanks @mbelinky. - Cron/subagent followup: do not misclassify empty or `NO_REPLY` cron responses as interim acknowledgements that need a rerun, so deliberately silent cron jobs are no longer retried. (#41383) thanks @jackal092927. +- Auth/cooldowns: reset expired auth-profile cooldown error counters before computing the next backoff so stale on-disk counters do not re-escalate into long cooldown loops after expiry. (#41028) thanks @zerone0x. ## 2026.3.8 diff --git a/src/agents/auth-profiles/usage.ts b/src/agents/auth-profiles/usage.ts index 19f3a030fad..0d9ae6a6aaa 100644 --- a/src/agents/auth-profiles/usage.ts +++ b/src/agents/auth-profiles/usage.ts @@ -406,15 +406,8 @@ function computeNextProfileUsageStats(params: { // the old counters when the lock-based updater reads a fresh store. Without // this check, stale error counts from an expired cooldown cause the next // failure to escalate to a much longer cooldown (e.g. 1 min → 25 min). - const previousCooldownExpired = (() => { - const unusableUntil = resolveProfileUnusableUntil(params.existing); - // No cooldown/disabled window was ever set → fresh profile, nothing to expire. - if (unusableUntil === null) { - return false; - } - // The window exists and has expired. - return params.now >= unusableUntil; - })(); + const unusableUntil = resolveProfileUnusableUntil(params.existing); + const previousCooldownExpired = typeof unusableUntil === "number" && params.now >= unusableUntil; const shouldResetCounters = windowExpired || previousCooldownExpired; const baseErrorCount = shouldResetCounters ? 0 : (params.existing.errorCount ?? 0);