666ghj/MiroFish · error · StarHistoryError

GitHub GraphQL edges were not a list

Error message

GitHub GraphQL edges were not a list

What it means

After the response envelope passed the dict-shape checks, data.repository.stargazers.edges was not a JSON array. The parser guards every node type strictly and refuses to iterate over a non-list, raising StarHistoryError('GitHub GraphQL edges were not a list'). It protects the subsequent per-edge loop from blowing up with a less clear TypeError.

Source

Thrown at scripts/star_history.py:269

            raw_edges = stargazers["edges"]
            page_info = stargazers["pageInfo"]
        except (KeyError, TypeError) as exc:
            raise StarHistoryError("GitHub GraphQL response had an unexpected shape") from exc

        if not all(
            isinstance(value, dict)
            for value in (data, repository, stargazers, rate_limit, page_info)
        ):
            raise StarHistoryError("GitHub GraphQL response had an unexpected shape")

        total_count = _strict_non_negative_int(
            stargazers.get("totalCount"), "GraphQL totalCount"
        )
        rate_remaining = _strict_non_negative_int(
            rate_limit.get("remaining"), "GraphQL rate remaining"
        )
        if not isinstance(raw_edges, list):
            raise StarHistoryError("GitHub GraphQL edges were not a list")

        edges: list[StargazerEdge] = []
        for raw_edge in raw_edges:
            if not isinstance(raw_edge, dict):
                raise StarHistoryError("GitHub GraphQL returned an invalid edge")
            cursor = raw_edge.get("cursor")
            starred_at = raw_edge.get("starredAt")
            if not isinstance(cursor, str) or not cursor:
                raise StarHistoryError("GitHub GraphQL returned an invalid edge cursor")
            if not isinstance(starred_at, str):
                raise StarHistoryError("GitHub GraphQL returned an invalid star timestamp")
            edges.append(StargazerEdge(cursor, _parse_github_timestamp(starred_at)))

        has_next_page = page_info.get("hasNextPage")
        end_cursor = page_info.get("endCursor")
        if type(has_next_page) is not bool:
            raise StarHistoryError("GitHub GraphQL returned invalid page information")
        if end_cursor is not None and not isinstance(end_cursor, str):

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Log the raw stargazers sub-object when this fires to see whether edges is null or an object
  2. If edges is null because the connection is unavailable, treat that as the same case as error 120 and check the top-level errors array / token scopes
  3. Fix any local modification of the query string that dropped the edges [] selection

Example fix

// before
raw_edges = stargazers["edges"]

// after
raw_edges = stargazers.get("edges") or []  # only if a null connection is expected; otherwise keep raising
Defensive patterns

Strategy: validation

Validate before calling

edges = (payload["data"]["repository"].get("stargazers") or {}).get("edges")
if edges is None:
    raise StarHistoryError("stargazers connection missing — check token scopes and repo visibility")

Type guard

def has_edge_list(payload: dict) -> TypeGuard[dict]:
    sg = payload.get("data", {}).get("repository", {}).get("stargazers", {})
    return isinstance(sg, dict) and isinstance(sg.get("edges"), list)

Try / catch

try:
    page = _parse_graphql_page(payload)
except StarHistoryError as exc:
    if "edges were not a list" in str(exc):
        logger.warning("stargazers edges missing for repo; treating as empty page")
        page = StargazerPage(0, (), False, None, 0)
    else:
        raise

Prevention

When it happens

Trigger: A GraphQL response where stargazers.edges is null (e.g. repository exists but stargazers connection returned null), an object keyed by cursor instead of a list, or a truncated/malformed payload from a proxy.

Common situations: GitHub returning stargazers: null for an inaccessible or empty connection; a modified GraphQL query that aliased or restructured edges; a mocked/stubbed API in tests returning a dict of edges.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/0a0a79dd3ec377a1. Report an issue: GitHub.