tinyhumansai/openhuman · error

failed ( )

Error message

{} {} failed ({status}): {text}

What it means

The generic non-2xx failure from authed_json: after emitting an observability span with method/path/host/status and failure=non_2xx attributes, it bails with '{method} {path} failed ({status}): {text}'. Any authenticated backend response outside 2xx that is not specially handled (401 session expiry, channel-message 404, announcements 404) lands here, with the response body text embedded.

Solutions

  1. Branch on the {status} embedded in the message: 4xx fix the request, 429 back off, 5xx retry later.
  2. Correlate with the emitted span attributes (method, path, host, status) in your telemetry backend.
  3. Align app, SDK, and backend versions if a route or contract changed.
  4. For 5xx storms, check backend status before assuming a client bug.
Defensive patterns

Strategy: try-catch

Try / catch

Parse the status out of the message with a regex like /failed \((\d+)\)/ and branch: 401 -> refresh session; 429 -> back off with the Retry-After hint; 5xx -> retry later with jitter; other 4xx -> fix the request. Correlate with the emitted span attributes (method, path, host, status).

Prevention

When it happens

Trigger: 4xx from request shapes the backend rejects outright; 429 rate limiting; 5xx during a backend incident or deploy window; gateway 502/504 timeouts - all on any authed_json or IntegrationClient route.

Common situations: Backend outage or rolling deploy; payload schema drift between app and backend; hammering an endpoint past its rate limit; proxy or corporate TLS middleware injecting errors.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/api/rest.rs:848

                        "{} {} failed ({status}); response_body_len={}; body_shape={}",
                        method.as_str(),
                        url.path(),
                        text.len(),
                        body_shape,
                    )
                    .as_str(),
                    "backend_api",
                    "authed_json",
                    &[
                        ("method", method.as_str()),
                        ("path", url.path()),
                        ("host", host),
                        ("status", status_str.as_str()),
                        ("failure", "non_2xx"),
                    ],
                );
            }
            anyhow::bail!(
                "{} {} failed ({status}): {text}",
                method.as_str(),
                url.path()
            );
        }
    }

    /// Lists all active integrations for the current user.
    pub async fn list_integrations(&self, bearer_jwt: &str) -> Result<Vec<IntegrationSummary>> {
        let value = self
            .authed_json(bearer_jwt, Method::GET, "auth/integrations", None)
            .await?;
        let integrations = value
            .get("integrations")
            .cloned()
            .unwrap_or_else(|| value.clone());
        serde_json::from_value(integrations).context("parse integrations response")
    }

View on GitHub (pinned to 7491200858)