agent's unsubscribed-contact check ran against a 12-hour-stale cached list - it emailed 90 opted-out leads
For sales-outreach (SDR) agents: Never trust one timestamp-free payload. Cross-check freshness before the agent acts on it: require a recency field, compare against a second source on high-stakes fields, and expire cached rows aggressively. Stale data fails silently, which is why it is worse than an error.
TL;DR
Never trust one timestamp-free payload. Cross-check freshness before the agent acts on it: require a recency field, compare against a second source on high-stakes fields, and expire cached rows aggressively. Stale data fails silently, which is why it is worse than an error.
The query
agent's unsubscribed-contact check ran against a 12-hour-stale cached list - it emailed 90 opted-out leadsUse this when
- the agent acted on data that turned out to be months or years old
- cached rows have no date or the provider's cache is known to lag
Not for
- data that is wrong at the source (that is a provider-quality problem)
- schema changes that break parsing (see the parsing skill)
Steps
Step 1: Find where the stale value entered the pipeline
Trace the field back: which provider, which cache layer, which row. Check the payload for a date or updated-at field. If there is none, that is the root cause: the agent cannot tell fresh from rotten.
**Expected: the exact cache or provider row that served the stale value, with its age.
Step 2: Quarantine the affected outputs
List every message, decision, or write the agent made from the stale value. Pause further sends that depend on that field until the data is refreshed. Stale-data incidents widen while the agent keeps running.
**Expected: a list of affected leads/messages; dependent steps paused.
Step 3: Refresh from source and add a freshness gate
Re-pull the data from the authoritative source and require a recency check before use: reject rows older than your threshold (e.g. 30 days for employment data) or flag them for human review. No date on the payload means treat it as suspect by default.
**Expected: refreshed rows with verified dates; the gate rejects or flags stale rows.
Step 4: Add a second-source check for high-stakes fields
For fields that change outcomes (job title, company status, employee count), compare two providers and flag disagreements instead of picking one silently. Disagreement is a signal, not noise.
**Expected: mismatched fields raise a review flag instead of flowing into messages.
Step 5: Shrink the cache TTL for volatile fields
Employment, funding, and headcount data rot fast. Set TTLs in days, not months, for volatile fields, and log cache age on every read so the next incident shows its age immediately.
**Expected: cache reads carry an age; nothing older than the TTL is served.
Why it happens
Enrichment and cache layers serve old snapshots without saying so. Agents treat the payload as current because nothing in it says otherwise, so a 2021 funding round reads as 'recent' and a dead company reads as a prospect.
Edge cases
- Two providers can both be stale; agreement is not proof of freshness.
- Replication lag makes 'just written' data look stale; distinguish lag from rot by checking the writer.
- Over-aggressive TTLs burn enrichment credits; tier TTLs by field volatility.
Finding this skill
This skill was written for sales-outreach (SDR) agents hitting the failure above. Search Vectle for the exact error text or symptom to find it and related skills.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstMi8WwiNCtHOqGMiCvCsYw