zed-industries/zed · error · FetchError
Sentry API returned HTTP {err.code} for {path}: {detail}
Error message
Sentry API returned HTTP {err.code} for {path}: {detail} What it means
Raised by api_get() in script/sentry-fetch when the Sentry API returns a 4xx/5xx (urllib HTTPError). Unlike its counterpart in select-sentry-crash-candidates, this urlopen call sets no timeout, so the HTTPError path is reached only after the server actually responded with an error status. The detail is Sentry's JSON 'detail' when parseable, else the raw body.
Source
Thrown at script/sentry-fetch:108
return None
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
View on GitHub (pinned to bc538def45)
Solutions
- Confirm the issue exists in the org the script targets (DEFAULT_SENTRY_ORG) via the Sentry UI
- For short IDs, pass the exact short_id shown by Sentry for that org
- Refresh the SENTRY_TOKEN and confirm event:read/org:read scopes
- Treat 404 as 'issue gone' and skip it rather than aborting the whole batch
Example fix
# before
if identifier.isdigit():
issue = api_get(f"/issues/{identifier}/", token)
# after: distinguish gone-vs-auth failures for batch runs
try:
issue = api_get(f"/issues/{identifier}/", token)
except FetchError as error:
if "HTTP 404" in str(error):
log(f"issue {identifier} no longer exists; skipping")
continue
raise Defensive patterns
Strategy: try-catch
Validate before calling
# Validate identifier shape before resolving
if not (identifier.isdigit() or ("-" in identifier and len(identifier.split("-")) == 2)):
sys.exit(f"not a numeric id or SHORTID: {identifier!r}") Type guard
def is_numeric_issue_id(identifier: str) -> bool:
return identifier.isdigit() Try / catch
try:
issue_id, short_id, issue = resolve_issue(identifier, token)
except FetchError as error:
if "HTTP 404" in str(error):
print(f"{identifier}: not found in org {DEFAULT_SENTRY_ORG}; skipping")
continue
if "HTTP 401" in str(error):
sys.exit("SENTRY_TOKEN rejected — refresh it")
raise Prevention
- Keep issue ids from the same org the script targets (DEFAULT_SENTRY_ORG)
- Treat 404 as skippable in batch runs instead of fatal
- Refresh tokens on a schedule so cron runs do not die on 401
When it happens
Trigger: resolve_issue() hitting /issues/{id}/ with an unknown numeric id (404); /organizations/{DEFAULT_SENTRY_ORG}/shortids/{short}/ with a short ID from another org (404); /issues/{id}/events/latest/ on a deleted issue (404); 401 from a revoked token; 403 from a token missing event:read scope.
Common situations: DEFAULT_SENTRY_ORG in the script does not match where the crash issue lives; token expired between cron runs; issue was resolved-and-deleted in Sentry before the fetch; typo'd short ID like ABC-123 vs the plain short part.
Related errors
- Sentry API returned HTTP {error.code} for {path}: {detail}
- unknown benchmark '{benchmark_id}' (valid: {valid})
- unknown benchmark '{selector}' (valid: {valid})
- could not locate run '{run_id}' in the local run index ({run
- Failed to connect to Sentry API: {error.reason}
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/7ccac7a8202b3d7c.
Report an issue: GitHub.