tinyhumansai/openhuman · error · BackendApiError::AnnouncementNotFound

no announcement available (404 on /announcements/latest)

Error message

no announcement available (404 on /announcements/latest)

What it means

A 404 on GET /announcements/latest is semantically "no announcement right now", so authed_json maps it to the typed AnnouncementNotFound; the announcements caller degrades to null instead of propagating an error. Best-effort cosmetic path, never reported to Sentry.

Source

Thrown at src/api/rest.rs:780

                        url.path(),
                    );
                }

                // 404 on `/announcements/latest` means "no announcement" for
                // this best-effort, cosmetic feature — not a code bug. Surface
                // a typed `BackendApiError::AnnouncementNotFound` so the caller
                // (`announcements::ops::get_latest_announcement`) can degrade to
                // `null` instead of propagating an error, without funneling the
                // 404 into `report_error`. Targets `TAURI-RUST-HW0` / `TAURI-RUST-KHX`.
                if method == Method::GET && is_announcements_latest_path(url.path()) {
                    tracing::info!(
                        domain = "backend_api",
                        operation = "authed_json",
                        "[backend_api] announcement-not-found 404 on {} {} — surfacing typed error",
                        method.as_str(),
                        url.path(),
                    );
                    return Err(anyhow::Error::new(BackendApiError::AnnouncementNotFound));
                }
            }

            // These are transient infrastructure errors (proxy/CDN/backend
            // temporarily unavailable). They are not code bugs and callers already
            // implement retry/disable logic, so skip Sentry to avoid noise.
            let is_transient_infra =
                crate::core::observability::is_transient_http_status_code(status_code);
            let is_budget_exhausted = status_code == 400
                && crate::openhuman::inference::provider::is_budget_exhausted_message(&text);
            if is_budget_exhausted {
                tracing::info!(
                    method = method.as_str(),
                    path = url.path(),
                    status = status_code,
                    failure = "non_2xx",
                    kind = "budget",
                    "[backend_api] budget-exhausted 400 on {} {} — not reporting to Sentry",

View on GitHub (pinned to 7491200858)

Solutions

  1. Treat as the empty state — render no announcement
  2. No corrective action needed; it clears when a new announcement is published
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at src/api/rest.rs:780 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/ad986534f5267f75. Report an issue: GitHub.