astrid-runtime/astrid · error
GitHub API error querying release tag {candidate} for {org}/
Error message
GitHub API error querying release tag {candidate} for {org}/{repo}: HTTP {} What it means
resolve_github_ref queries the GitHub API for a release with the requested tag. Any non-success, non-404 HTTP status (404 is treated as 'try next candidate') aborts resolution with this error, because the CLI cannot determine whether the pinned version exists.
Source
Thrown at crates/astrid-cli/src/commands/capsule/install_github.rs:68
org: &str,
repo: &str,
version: Option<&str>,
tag: Option<&str>,
) -> anyhow::Result<String> {
if let Some(tag) = tag {
return Ok(tag.to_string());
}
if let Some(version) = version {
for candidate in [format!("v{version}"), version.to_string()] {
let tag_url = release_tag_url(org, repo, &candidate)?;
let response = client.get(&tag_url).send().await.with_context(|| {
format!("failed to query release tag {candidate} for {org}/{repo}")
})?;
if response.status() == reqwest::StatusCode::NOT_FOUND {
continue;
}
if !response.status().is_success() {
bail!(
"GitHub API error querying release tag {candidate} for {org}/{repo}: HTTP {}",
response.status()
);
}
let json = response
.json::<serde_json::Value>()
.await
.with_context(|| format!("invalid GitHub API response for tag {candidate}"))?;
return Ok(json
.get("tag_name")
.and_then(serde_json::Value::as_str)
.unwrap_or(&candidate)
.to_string());
}
bail!("no GitHub release found for version {version} in {org}/{repo}");
}
tracing::debug!(%org, %repo, "no version/tag pin — resolving latest release");View on GitHub (pinned to affd8760f4)
Solutions
- Retry after waiting if the status is 403/429 — likely GitHub API rate limiting; set GITHUB_TOKEN to raise the limit.
- Check https://www.githubstatus.com for GitHub API incidents if you see 5xx.
- Verify the repo is public or provide credentials for a private repo (403).
- Check network/proxy configuration that might intercept api.github.com requests.
Example fix
// before (unauthenticated, rate-limited) astrid capsule install github:org/repo@1.2.0 // after (authenticated, higher rate limit) export GITHUB_TOKEN=ghp_... astrid capsule install github:org/repo@1.2.0
Defensive patterns
Strategy: retry
Try / catch
// retry transient GitHub failures with backoff
for attempt in 0..3 {
match install_capsule_from_github("org", "repo", Some("1.2.0")).await {
Ok(_) => break,
Err(e) if e.to_string().contains("GitHub API error") && attempt < 2 => {
tokio::time::sleep(std::time::Duration::from_secs(2u64.pow(attempt))).await;
}
Err(e) => return Err(e),
}
} Prevention
- Set GITHUB_TOKEN to avoid unauthenticated rate limits.
- Check GitHub API status before bulk installs in CI.
- Handle 403/429 with exponential backoff in automation.
When it happens
Trigger: install_from_github or resolve_capsule_to_file calls resolve_github_ref with a version pin; the GET to api.github.com/repos/{org}/{repo}/releases/tags/{candidate} returns a 4xx/5xx status other than NOT_FOUND.
Common situations: GitHub API rate limiting (403/429) from an unauthenticated client; a GitHub outage (5xx); a private repo returning 403 for an unauthenticated request; corporate proxy blocking api.github.com.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- GitHub API returned {} fetching release {resolved_ref} of {o
- GitHub API returned {} for {org}/{repo} latest release
- release {resolved_ref} of {org}/{repo} ships no .capsule ass
- no GitHub releases found for {org}/{repo}
- GitHub API rate limit exceeded - try again later
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/a6d2b149def21f33.
Report an issue: GitHub.