zed-industries/zed · error
status error {}, response: {text:?}
Error message
status error {}, response: {text:?} What it means
After fetching Forgejo commit details from /api/v1/repos/{owner}/{repo}/git/commits/{sha}, any HTTP 4xx status bails with the numeric code plus the raw response body text. It means the Forgejo instance itself rejected the request: 404 for an unknown repo/owner/commit, 401/403 for missing or under-scoped tokens, 429 for rate limiting. Only is_client_error() takes this path; server 5xx errors instead surface later as a deserialization failure.
Source
Thrown at crates/git_hosting_providers/src/providers/forgejo.rs:144
// TODO: not renamed yet for compatibility reasons, may require a refactor later
// see https://github.com/zed-industries/zed/issues/11043#issuecomment-3480446231
if host == "codeberg.org"
&& let Ok(codeberg_token) = std::env::var("CODEBERG_TOKEN")
{
request = request.header("Authorization", format!("Bearer {}", codeberg_token));
}
let mut response = client
.send(request.body(AsyncBody::default())?)
.await
.with_context(|| format!("error fetching Forgejo commit details at {:?}", url))?;
let mut body = Vec::new();
response.body_mut().read_to_end(&mut body).await?;
if response.status().is_client_error() {
let text = String::from_utf8_lossy(body.as_slice());
bail!(
"status error {}, response: {text:?}",
response.status().as_u16()
);
}
let body_str = std::str::from_utf8(&body)?;
serde_json::from_str::<CommitDetails>(body_str)
.map(|commit| commit.author)
.context("failed to deserialize Forgejo commit details")
}
}
#[async_trait]
impl GitHostingProvider for Forgejo {
fn name(&self) -> String {
self.name.clone()
}View on GitHub (pinned to f4178619ac)
Solutions
- Verify the triple exists: open {base}/api/v1/repos/{owner}/{repo}/git/commits/{sha} in a browser or with curl using the same token
- If 401/403, check the token is set, valid, and has read access to that repository
- Treat 404 as Ok(None) when the author is only optional enrichment, instead of propagating an error
- For 429, back off and retry honoring Retry-After
Example fix
// before
if response.status().is_client_error() {
bail!("status error {}, response: {text:?}", response.status().as_u16());
}
// after: 404 means 'unknown commit', not a hard failure
let status = response.status();
if status.as_u16() == 404 {
return Ok(None);
}
if status.is_client_error() {
bail!("status error {}, response: {text:?}", status.as_u16());
} Defensive patterns
Strategy: try-catch
Try / catch
match provider.commit_author(owner, repo, sha).await {
Ok(author) => { /* render author */ }
Err(err) if err.to_string().contains("status error 404") => {
// unknown repo/commit: treat as absent rather than an error
}
Err(err) if err.to_string().contains("status error 429") => {
// back off and retry honoring Retry-After
}
Err(err) => return Err(err),
} Prevention
- Derive owner/repo/commit from parsed VCS remotes and refs, not hand-typed strings
- Cache 404 results so unknown commits are not re-fetched
- Keep tokens valid and scoped; refresh before expiry
- Never treat a 4xx body as parseable JSON — log it verbatim for diagnosis
When it happens
Trigger: Calling the commit-author lookup with a wrong owner/repo pair, a commit sha that does not exist on that Forgejo instance (not pushed, or a sha from a fork), a missing/expired access token on a private repo (401/403), or polling fast enough to hit rate limits (429).
Common situations: Typo'd repository identifiers in a permalink; a commit not yet pushed or fetched so the server does not know the sha; a CI job using a token without read scope for the repo; aggressive polling of commit metadata.
Related errors
- failed to get host from forgejo base url
- could not locate run '{run_id}' in the local run index ({run
- Failed to connect to API: {} {}
- Failed to connect to API: {} {}
- status error {}, response: {text:?}
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/9365856a86af751e.
Report an issue: GitHub.