A routine Claude Max OAuth token rotation (~8h) fails the in-flight call with
401 authentication_error "Invalid authentication credentials" even though
refreshed credentials already exist on disk. Three compounding defects turned
that into a fleet-wide operator-action park:
- The heartbeat prompt path never ran under withRateLimitRetry (executor/
triage/merger all do), so the 401 immediately failed the run. Now wrapped.
- The 401 matched the operator-actionable /credential/ pattern and defaulted
to "permanent", so FN-7859 parked agents paused/error-unrecoverable. A new
shared isTransientAuthCredentialError classifier (also used by
rate-limit-retry) classifies rotation 401s transient + not operator-
actionable; OAuth scope-grant and API-key failures still park.
- Heartbeat failure classification ran on the stack-bearing error detail;
stack frames like "at withRateLimitRetry (.../rate-limit-retry.ts)" match
the usage-limit /rate[_\s]?limit/ pattern. Classification and
agent.lastError now use the message; stderrExcerpt keeps the full detail.
Self-healing additionally un-parks agents previously paused with
error-unrecoverable whose lastError now classifies recoverable, bounded by
the shared heartbeat error-recovery budget.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>