## TL;DR
Long runs outlive short-lived credentials. If the agent authenticates once at start and scores for hours, expiry mid-run is arithmetic, not bad luck. Refresh before the run, track expiry inside the run, and re-authenticate at batch boundaries so a refresh never interrupts an account write halfway.

```text
auth token expired mid-health-score run: agent failed to refresh credentials
```

## Use this when
- Run logs show authentication failures starting partway through, not at launch
- Credential lifetime is shorter than the run duration
- Early accounts score fine and later accounts fail

## Not for this skill when
- The credential was revoked or its permissions were reduced
- All calls fail from the start, indicating wrong credentials entirely

## Steps
1. Measure credential lifetime and the run's duration distribution. Verify: the overlap (runs longer than credential life) is quantified
2. Check where the code obtains credentials: once at start, per call, or cached without expiry awareness. Verify: the acquisition pattern that guarantees mid-run expiry is located
3. Implement refresh at start and at batch boundaries, keyed to the expiry timestamp minus a safety margin. Verify: a long test run crosses an expiry boundary without a failed call
4. Make account scoring idempotent so a batch retried after re-authentication does not double-write. Verify: retried batches produce one score per account
5. Alert on refresh failures as their own signal, separate from scoring failures. Verify: credential problems page as credential problems, with time to act

## Variant phrasings
### agent credentials expire during long run
A related phrasing for the same underlying problem.
### mid-run authentication failure scoring
A related phrasing for the same underlying problem.
### refresh credentials at batch boundary
A related phrasing for the same underlying problem.

Compatibility: Compatibility: OAuth-based API access from agent runtimes (Salesforce, HubSpot, warehouse connectors), current versions.

## Why it happens
Expiry mid-run is a scheduling fact: any run longer than the credential's life will hit it deterministically. The fix is architectural (refresh inside the run's rhythm, idempotent batches) rather than asking for longer-lived credentials, which trades a reliability bug for a security problem.

## Edge cases / pitfalls
- Refresh at batch boundaries, not mid-account, or a failed refresh strands a half-written account.
- Some providers rotate the refresh credential on use. Persist the rotated value immediately or the next run starts dead.
- A safety margin of a few minutes before expiry covers clock differences between the agent host and the API.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_6dX4yk1RRV-qsctmRXb9Ew
