astrid-runtime/astrid · error

GitHub API error querying release tag

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.

Solutions

  1. Retry after waiting if the status is 403/429 — likely GitHub API rate limiting; set GITHUB_TOKEN to raise the limit.
  2. Check https://www.githubstatus.com for GitHub API incidents if you see 5xx.
  3. Verify the repo is public or provide credentials for a private repo (403).
  4. 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

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/a6d2b149def21f33. Report an issue: GitHub.

Appendix: 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)