How Tempio says what it does not know
Every tool result carries a warnings array — seven classes over an open code set, three severities, and a deep-link to the record each one is about. This note is what an agent should do with each severity and each class.
Last reviewed 2026-09-13.
A warning is how Tempio says something true about an answer that the answer
itself cannot carry. It never changes a value: fx_estimate_applied does not
round a number and stale_last_synced does not hide one. warnings is always
present on a result and is [] when there is nothing wrong, because a consumer
that has to test whether a field exists learns nothing from its absence.
The seven classes
The class is the stable thing to branch on. The code set is deliberately open —
adapters add to it — and an unmapped code degrades to other at info and
keeps whatever message it arrived with, rather than taking out a read.
stale_sync— the numbers are older than they look, or incomplete.stale_last_synced,partial_sync,never_synced,today_incomplete,report_truncated.connection_expired— a grant needs re-authorising, and until it does this platform's rows stop moving.permission_missing— the credential cannot do what was asked, and what it would need.write_gate_closed— a draft cannot be written here, said before one is attempted.budget_guardrail— the amount is close to, or over, a cap, said on the read rather than only at the refusal.near_daily_cap,delta_large,recent_increases_high.currency— the money is not what it appears to be.fx_estimate_applied,currency_mixed_scope,ranking_raw,undefined_ratio_present,stamped_currency_changed.other— the degrade target for a code no registry row covers, and the home of the codes that are none of the above,playbook_staleamong them.
The three severities, and what to do
info— context a careful answer mentions once. Do not lead with it and do not bury it.degraded— the answer is usable and is not the whole truth. State it before the number it travels with. "These are from the last sync, not from now — spend over the window was …" is the order; the same sentence after the figure is a footnote nobody reads.blocking— the thing it names is unavailable. Do not infer the value from a neighbouring figure, do not estimate it, and do not retry the call hoping for a different answer. Say what is blocked, say what would clear it, and stop.
A warning about the WORKSPACE rather than about the answer in front of it is
held at degraded on the way out: one revoked TikTok grant must not read as
blocking on a Meta-only metrics call, because blocking instructs a model to
stop. The condition is still reported, with its own copy and its own link. A
tool genuinely refusing something says so at its own severity.
The subject
A warning that is about a record carries subject: a kind, the record's
id, and an absolute url. The URL is built from the ROW, never from a bare
id, which is what makes it org-safe by construction — the only way to hold a
row is a query that already filtered the workspace, so an id from another
workspace never produces a URL because it never produces a row. Hand that URL
to a person: an agent's reader cannot open /connections?connection=abc.
The kinds are the entities the product has pages for — draft, batch,
campaign, ad_group, ad, plan, media, connection, account, the
library's library_advertiser, library_ad and swipe, and playbook. The
URL still requires a session, and the page still checks membership; a link is
not a grant.
Playbooks
Two codes are about this shelf itself. playbook_stale (other, info) says
a playbook was last reviewed more than ninety days ago and the platform may
have changed since — quote it when you lean on that playbook's advice.
playbook_missing (other, info) says no playbook is published for a
platform yet, so the agent has only its own knowledge there. Both are honest
about age and absence, which is the only reason a corpus is worth trusting.
The rule underneath
Say the condition once, in the registry's own sentence, in the same words the app's warning strip uses — a page and an agent must never say different things about one condition. Then answer the question. Failing to compute a warning never takes the answer away, and quoting a number without the warning attached to it is the one thing this whole mechanism exists to prevent.
Sources
- WARNING_CLASSES, WARNING_SEVERITIES, WARNING_REGISTRY, toWarning, cappedSeverity —
repo://apps/app/lib/ads/warnings.ts(read 2026-09-13) - The envelope, and the context-level warnings held at degraded —
repo://apps/app/lib/ads/tools/run.ts(read 2026-09-13) - deepLink and LINK_PATTERNS — what a warning's subject points at —
repo://apps/app/lib/ads/links.ts(read 2026-09-13) - The API reference's envelope and warning sections —
repo://apps/docs/content/docs/api/index.mdx(read 2026-09-13)