zed-industries/zed · error · FetchError

Failed to connect to Sentry API: {err.reason}

Error message

Failed to connect to Sentry API: {err.reason}

What it means

Raised by api_get() in script/sentry-fetch when urllib raises URLError before any HTTP response arrives: DNS failure, connection refused, TLS error, or proxy failure. Note this script's urlopen(req) passes no timeout argument, so a silently hanging connection can also manifest here only once the OS gives up — or the script can appear to hang indefinitely before erroring.

Source

Thrown at script/sentry-fetch:110

def api_get(path, token):
    """Make an authenticated GET request to the Sentry API."""
    url = f"{SENTRY_BASE_URL}{path}"
    req = urllib.request.Request(url)
    req.add_header("Authorization", f"Bearer {token}")
    req.add_header("Accept", "application/json")
    try:
        with urllib.request.urlopen(req) as response:
            return json.loads(response.read().decode("utf-8"))
    except urllib.error.HTTPError as err:
        body = err.read().decode("utf-8", errors="replace")
        try:
            detail = json.loads(body).get("detail", body)
        except (json.JSONDecodeError, AttributeError):
            detail = body
        raise FetchError(f"Sentry API returned HTTP {err.code} for {path}: {detail}")
    except urllib.error.URLError as err:
        raise FetchError(f"Failed to connect to Sentry API: {err.reason}")


def resolve_issue(identifier, token):
    """Resolve a Sentry issue by short ID or numeric ID.

    Returns (issue_id, short_id, issue_data).
    """
    if identifier.isdigit():
        issue = api_get(f"/issues/{identifier}/", token)
        return identifier, issue.get("shortId", identifier), issue

    result = api_get(f"/organizations/{DEFAULT_SENTRY_ORG}/shortids/{identifier}/", token)
    group_id = str(result["groupId"])
    issue = api_get(f"/issues/{group_id}/", token)
    return group_id, identifier, issue


def fetch_latest_event(issue_id, token):

View on GitHub (pinned to bc538def45)

Solutions

  1. Verify basic reachability: curl -sS https://sentry.io/api/0/ from the same shell
  2. Export HTTPS_PROXY if the environment requires an egress proxy
  3. Add a timeout to urllib.request.urlopen(req, timeout=30) so hangs fail fast instead of blocking
  4. Check status.sentry.io for incidents

Example fix

# before
with urllib.request.urlopen(req) as response:
    return json.loads(response.read().decode("utf-8"))

# after
with urllib.request.urlopen(req, timeout=30) as response:
    return json.loads(response.read().decode("utf-8"))
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight egress and set proxy env before importing/running
import os, socket

for host in ("sentry.io",):
    try:
        socket.create_connection((host, 443), timeout=5).close()
    except OSError as error:
        if not os.environ.get("HTTPS_PROXY"):
            print("no egress and no HTTPS_PROXY set — set it and retry")
        raise

Try / catch

try:
    data = api_get(path, token)
except FetchError as error:
    if "Failed to connect" not in str(error):
        raise
    if attempt < max_retries:
        time.sleep(2 ** attempt); continue
    raise

Prevention

When it happens

Trigger: No network route to sentry.io from where sentry-fetch runs; required HTTPS_PROXY missing; DNS failure for the Sentry host; TLS interception with an untrusted CA; Sentry outage.

Common situations: Cron/devbox without proxy env vars; container with broken resolv.conf; corporate MITM proxy cert not in the Python trust store; running offline.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/753dbf21c3d38c67. Report an issue: GitHub.