agent's session token expired mid-run: auth error, kept retrying unauthenticated
Teaches an agent that 401s are not retryable without a refresh: fail fast on auth errors, refresh the session once, resume, and never hammer an endpoint unauthenticated. Use when an agent loops on 401s. Not for 429s or 500s, which are retryable.
TL;DR
A 401 means the session is dead; retrying the same request changes nothing. The agent must treat 401 as non-retryable without a credential refresh: stop, refresh the session once, verify, resume from the checkpoint, and cap the whole cycle so it can never loop.
Error
agent's session token expired mid-run: auth error, kept retrying unauthenticatedSteps
- Classify the 401 immediately as "needs refresh", not "try again". Expected: zero unauthenticated retries.
- Refresh the session credential through the proper flow. Expected: a new valid session.
- Verify the refresh with one cheap authenticated call. Expected: proof the session works before resuming.
- Resume from the last checkpoint. Expected: progress continues, nothing repeats.
- If the refresh itself fails, escalate instead of retrying the refresh in a loop. Expected: a human resolves credential problems.
When to use
- An agent retries API calls that return 401.
- Any session-based API workflow.
When not to use
- 429 rate limits (backoff and retry is correct there).
- 500 server errors (retry the request; the session is fine).
Tool compatibility
- Any session-authenticated API, including dbt Cloud and warehouses.
Variant phrasings
Agent treats 401 like 500
The core confusion: 401 is about the credential, 500 is about the server.
Refresh loop: new token also 401s
The refresh flow itself is broken; escalate after one failure.
Why it happens
Generic retry logic retries every error equally. For 401s that means hammering an endpoint that will never accept the dead session, sometimes tripping abuse detection on top of the original problem.
Edge cases
- A 401 immediately after a fresh refresh means the refresh flow is broken or the account was revoked; do not loop.
- Distinguish 401 (bad credential) from 403 (good credential, no permission); only 401 wants a refresh.
- Log the classification so the retry behavior is reviewable.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_WxWP7Uf3Hcrj0HXqZ6qgBw