Skip to content

GO hierarchy children capped at rows=10000 — truncates large terms (was unbounded under SPARQL); confirm latency-vs-completeness intent #162

Description

@kltm

Summary

GET /api/go/{id}/hierarchy silently truncates its children list at rows=10000. For GO terms with more than ~10k descendants (the ontology roots and high-level terms), results are dropped with no error or indication.

Example — GO:0008150 (the biological_process root), v0.4.0 build vs current production 0.3.9:

build hierarchy items
production 0.3.9 (api.geneontology.org) 24,450
0.4.0 (Blazegraph-removed) 10,001

This is an accidental regression, not an intentional cap

  • The old implementation was a SPARQL query with no LIMIT — unbounded, returned all rows.
  • The new GOlr children query introduced the cap: app/routers/ontology.py:422optionals = "&rows=10000", in commit f776148 ("replace GO hierarchy SPARQL with golr query and add hierarchy tests") under PR Remove blazegraph: blazegraph dependency and replace with index gocam files #136 (umbrella Remove blazegraph dependencies in GO API #137).
  • The value is arbitrary and inconsistent within the same file: line 121 uses rows=100000; ontology_utils.py uses rows=1000. No comment justifies 10000.
  • It only manifests for terms with >10k descendants (the roots), so it is invisible in ordinary use.

No test catches it

The hierarchy tests added in the same commit only exercise small terms and assert structure, never completeness:

  • tests/unit/test_ontology_endpoints.py::test_go_hierarchy uses GO:0003677 ("DNA binding") and asserts only status == 200, isinstance(list), len > 0, and the parent/query/child keys.
  • tests/unit/test_ontology_utils.py::test_get_go_hierarchy_go_id loops small ids with len > 0 / status == 200.

Neither approaches the 10,000 boundary, so the truncation passes all tests.

Precedent

Row-default truncation has bitten this API before: #77 ("unexpected results after refactored code switchover" — a rows=100 default silently changed counts) and #138 (deliberately uses rows=-1 to avoid a cap). The isoform fix (#135) similarly used facet.limit=-1.

Proposed fix

  1. Remove the cap on the hierarchy children query — use rows=-1 (or rows=100000, matching ontology.py:121).
  2. Add a large-term regression test that would have caught this — e.g. assert the GO:0008150 hierarchy returns > 10,000 items.

Reproduction

# 0.3.9 (current production): 24450
curl -s "https://api.geneontology.org/api/go/GO:0008150/hierarchy" | python3 -c "import sys,json;print(len(json.load(sys.stdin)))"
# 0.4.0 build: 10001
curl -s "https://<0.4.0-host>/api/go/GO:0008150/hierarchy"        | python3 -c "import sys,json;print(len(json.load(sys.stdin)))"

— Posted by Claude Code agent on behalf of @kltm.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions