zed-industries/zed · error · RuntimeError

GraphQL error: {result['errors']}

Error message

GraphQL error: {result['errors']}

What it means

The github_graphql helper retries only HTTP-level transient statuses (RETRYABLE_STATUS_CODES with fixed delay); once a 200 arrives whose body contains an "errors" array it raises this RuntimeError immediately with the raw errors. GitHub GraphQL puts application failures (bad node ids, permission errors, schema problems) into a 200 body, so this error fires on query-level failures that retrying the HTTP call would not fix.

Source

Thrown at script/github-community-pr-board.py:280

def github_graphql(query, variables):
    """Execute a GitHub GraphQL query. Retries on transient server errors."""
    for attempt in range(MAX_RETRIES + 1):
        response = requests.post(
            f"{GITHUB_API_URL}/graphql",
            headers=GITHUB_HEADERS,
            json={"query": query, "variables": variables},
        )
        if response.status_code in RETRYABLE_STATUS_CODES and attempt < MAX_RETRIES:
            print(
                f"GitHub API returned {response.status_code}, retrying in {RETRY_DELAY_SECONDS}s (attempt {attempt + 1}/{MAX_RETRIES})..."
            )
            time.sleep(RETRY_DELAY_SECONDS)
            continue
        response.raise_for_status()
        result = response.json()
        if "errors" in result:
            raise RuntimeError(f"GraphQL error: {result['errors']}")
        return result["data"]
    raise RuntimeError("github_graphql: retry loop exited without return")


def github_rest_get(path):
    """GET from the GitHub REST API. Retries on transient server errors."""
    for attempt in range(MAX_RETRIES + 1):
        response = requests.get(f"{GITHUB_API_URL}/{path}", headers=GITHUB_HEADERS)
        if response.status_code in RETRYABLE_STATUS_CODES and attempt < MAX_RETRIES:
            print(
                f"GitHub API returned {response.status_code}, retrying in {RETRY_DELAY_SECONDS}s (attempt {attempt + 1}/{MAX_RETRIES})..."
            )
            time.sleep(RETRY_DELAY_SECONDS)
            continue
        response.raise_for_status()
        return response.json()
    raise RuntimeError("github_rest_get: retry loop exited without return")

View on GitHub (pinned to bc538def45)

Solutions

  1. Read the errors array inside the message: the type and message fields name the exact failing field or id
  2. Verify the token is valid and has read:project (plus write for the mutations in this script)
  3. Re-run the exact query with the same variables in a GraphQL client to isolate the failing fragment
  4. If the body errors are rate-limit messages, include them in the retry condition instead of raising on the first occurrence

Example fix

// before
result = response.json()
if "errors" in result:
    raise RuntimeError(f"GraphQL error: {result['errors']}")
return result["data"]

// after
result = response.json()
if "errors" in result:
    rate_limited = any("rate limit" in str(e.get("message", "")).lower() for e in result["errors"])
    if rate_limited and attempt < MAX_RETRIES:
        time.sleep(RETRY_DELAY_SECONDS)
        continue
    raise RuntimeError(f"GraphQL error: {result['errors']}")
return result["data"]
Defensive patterns

Strategy: retry

Validate before calling

def token_can_read_projects() -> bool:
    r = requests.get(f"{GITHUB_API_URL}/user", headers=GITHUB_HEADERS, timeout=30)
    return r.status_code == 200

Type guard

def is_graphql_error_body(payload: dict) -> bool:
    return isinstance(payload, dict) and bool(payload.get("errors"))

Try / catch

try:
    data = github_graphql(query, variables)
except RuntimeError as exc:
    if "rate limit" in str(exc).lower():
        time.sleep(RETRY_DELAY_SECONDS)
        data = github_graphql(query, variables)
    else:
        raise

Prevention

When it happens

Trigger: POST to GITHUB_API_URL/graphql for the community PR board query returns 200 + errors: project/item node ids from another org, token without project read, a ProjectV2 field fragment referencing a field GitHub deprecated, or mutation variables with wrong GraphQL types.

Common situations: GITHUB_TOKEN expired between scheduled runs; project or items recreated so cached node ids are stale; GitHub deprecating or renaming a ProjectV2 field in the schema; running against a different owner/repo than the token permits.

Related errors


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