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
- Branch on the {status} embedded in the message: 4xx fix the request, 429 back off, 5xx retry later.
- Correlate with the emitted span attributes (method, path, host, status) in your telemetry backend.
- Align app, SDK, and backend versions if a route or contract changed.
- 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
- Wrap authed_json calls in a single error-classification helper instead of string-matching at every call site.
- Never retry 4xx blindly - only 429 and 5xx are retryable.
- Emit the method/path/status tuple into logs when a route starts failing to spot backend incidents fast.
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
- API request failed
- Failed to send magic link
- HTTP error! status
- Backend error for
- Backend returned for DELETE
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)