tinyhumansai/openhuman · warning

channel message not found (404) on {} {}

Error message

channel message not found (404) on {} {}

What it means

Bailed by authed_json when a DELETE whose URL contains /channels/ and /messages/ came back 404 and the path was not matched by parse_message_path. This is a deliberate classification (TAURI-R7 defense-in-depth): the 404 is suppressed from Sentry and surfaced as a plain "message not found" error because an unmatched-route delete of an ephemeral message is expected, not a bug. Callers should treat it as "already gone", not as a hard failure.

Source

Thrown at src/api/rest.rs:759

                // Defense-in-depth: DELETE 404s on any channel-message path that
                // parse_message_path could not parse (e.g. exotic URL variant with extra
                // segments). Still an expected backend state — suppress the Sentry event
                // without propagating a typed error. Targets OPENHUMAN-TAURI-R7.
                // PATCH is handled above and returns the typed
                // `ChannelEditUnsupported` for both the parsed and unparsed shapes.
                if method == Method::DELETE
                    && url.path().contains("/channels/")
                    && url.path().contains("/messages/")
                {
                    tracing::debug!(
                        domain = "backend_api",
                        operation = "authed_json",
                        "[backend_api] channel-message 404 on {} {} — path not matched by \
                         parse_message_path, suppressing Sentry (TAURI-R7 defense-in-depth)",
                        method.as_str(),
                        url.path(),
                    );
                    anyhow::bail!(
                        "channel message not found (404) on {} {}",
                        method.as_str(),
                        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(),

View on GitHub (pinned to a221052e0d)

Solutions

  1. Treat this error as success for ephemeral-message cleanup — the goal (message absent) is achieved
  2. If the message should exist, verify the message_id format against the backend's route and parse_message_path expectations
  3. Do not wrap this specific 404 in retry loops; retrying a not-found delete cannot succeed

Example fix

// before
client.send_channel_delete(ch, msg_id, &jwt).await?; // hard error on 404

// after
if let Err(err) = client.send_channel_delete(ch, msg_id, &jwt).await {
    if err.to_string().starts_with("channel message not found (404)") {
        tracing::debug!("message already absent: {msg_id}");
    } else {
        return Err(err);
    }
}
Defensive patterns

Strategy: fallback

Type guard

fn is_channel_message_not_found(err: &anyhow::Error) -> bool {
    err.to_string().starts_with("channel message not found (404)")
}

Try / catch

if let Err(err) = client.send_channel_delete(ch, msg_id, &jwt).await {
    if is_channel_message_not_found(&err) {
        // Expected for ephemeral cleanup: the goal (message absent) is met.
        tracing::debug!(domain = "channel", "message already gone: {msg_id}");
    } else {
        return Err(err);
    }
}

Prevention

When it happens

Trigger: send_channel_delete targeting a thinking-indicator or ephemeral message the backend already purged, or a message_id whose route shape does not match parse_message_path (e.g. provider-native id format), yielding 404 on DELETE /channels/{ch}/messages/{id}.

Common situations: Cleanup of ephemeral messages racing with backend TTL purge, retrying a delete after the message was already deleted, or a channel whose backend routes were deployed later than the core.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/49072eca0ae2e7b8. Report an issue: GitHub.