## TL;DR

A stale FX rate cache misprices every cross-currency invoice until it is refreshed: three days of wrong prices is a cache-TTL failure. Put a short TTL on FX rates, alert when the cache age exceeds it, and fail the pricing step (rather than using a stale rate) when fresh rates are unavailable. Reprice the affected invoices and credit the differences.

```text
agent's FX rate cache went stale: cross-currency invoices mispriced for 3 days
```

## Use this when

- Cross-currency invoices were mispriced for days from a stale FX cache
- FX rates are cached without a TTL
- You need FX freshness guardrails

## Not for this skill when

- The FX rate source itself is wrong (provider data issue)
- A single invoice used the wrong currency (identification, not rates)
- You are debugging the rate provider's API

## Steps

1. Confirm the staleness: compare cached rates against the provider's rates for the affected days.
   Expected: The mispricing window is proven.
2. Reprice the affected invoices at the correct historical rates and credit or rebill the differences.
   Expected: Customers are made whole.
3. Set a TTL on the FX cache appropriate to rate volatility (minutes to hours, not days).
   Expected: Staleness is bounded.
4. Add a freshness check: pricing fails closed when the cache is older than the TTL.
   Expected: Stale rates can never price an invoice.
5. Alert on cache age and on rate jumps beyond a sane band.
   Expected: Anomalies get eyes quickly.
6. Log the rate and its timestamp on every priced invoice.
   Expected: Every price is auditable.

## Tool compatibility

FX rate providers; invoice pricing pipelines; cache TTL configuration.

## Variant phrasings

### stale FX rates invoice mispricing

The cause phrased directly.

### FX cache TTL cross-currency invoices

The mechanism phrasing.

### exchange rate cache freshness guardrail

The control-design angle.

## Why it happens

FX rates move continuously, so a cached rate has a shelf life measured in hours at most: using a three-day-old rate is pricing with fiction. The cache exists for performance, but without a TTL it silently becomes the system of record, and every invoice priced from it inherits the drift. Failing closed on stale rates (block pricing rather than guess) is the correct posture because a delayed invoice is cheaper than a mispriced one. Logging rate plus timestamp makes every historical price reconstructible, which is what lets you repair the damage precisely.

## Edge cases / pitfalls

- Historical rates for repricing must come from the provider's history API, not the current rate.
- Weekends and holidays have no fresh rates in some markets; define the policy for pricing then.
- Human review threshold: invoices above a value get a rate sanity check even with a fresh cache.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_emgiInLeIYUCf1a4F71N1g
