Skip to main content

Bug fixes

Enrichment probe cache staleness now self-heals in both directions (issue #911) The enrichment select-write guard (gtm-cd0ix, #904) probes Attio’s metadata API before every company upsert — attribute writability and active option titles, cached per (token, slug) — and caches had no expiry. Staleness has two directions, and only one of them self-healed: a cached writable verdict that went stale 400s the write, and the write-failure path cleared the caches so the next upsert re-probed. A cached dropped verdict (attribute archived or option unavailable) that went stale — the workspace re-added the option or un-archived the attribute — never failed a write, because the field was simply omitted. No failure, no invalidation: a long-running process kept discarding a now-valid value until restart. Both caches now store (value, expires_at) entries on the time.monotonic() clock with a ~300s TTL, so both drift directions recover without waiting for a write failure or a restart. The drop-with-warning window is bounded to the TTL instead of the process lifetime, while steady-state upserts stay off the metadata API entirely. The write-failure invalidation is also narrowed: it previously cleared both caches on every failure, including transient network/5xx errors, so a flaky window churned metadata probes (attribute list + options per affected slug) on every retry even when nothing about the schema changed. Clearing now fires only on schema-drift-shaped rejections — a parsed Attio 400 with code value_not_found (renamed/removed option or archived slug) or validation_type naming the select slug — reusing the describe_attio_error re-parse. The reserved-TLD domains value rejection captured in #888 shares the validation_type code but is a value problem, not schema drift, and is_domain_value_rejection keeps it excluded; body-less network errors and 5xx proxy failures (no Attio error body) fall out of the code check.
Last modified on October 5, 2026