Found in the re-review of #260 — the #262 fix covers the reported case but not the one its own docstring claims.
Ontologies.lookup's docstring says ADAPTER_ERROR means "the lookup could not be performed at all — a failed semsql download, an empty sqlite stub, an OAK change."
It does not cover the stub. ADAPTER_ERROR is returned only when get_adapter or adapter.label raises. A 0-byte or schema-only sqlite opens without error and returns label() == None for every id, so every pair falls through to UNRESOLVED — exactly the failure #262 described: the committed TSVs silently rewritten to ~1200 rows that read as a catastrophic corpus finding, exiting 0.
The wording is the more dangerous half, because it tells the next reader the case is handled.
scripts/validate_id_label_correspondence.py separates LOAD_FAILED from EMPTY_ADAPTER for this reason, and its _is_empty is an O(1) probe — next(iter(adapter.entities()), None) is None, with a positive stub confirmation if the probe itself raises, so a partially-migrated live ontology is not masked.
Fix: mirror that probe at adapter-open time and return ADAPTER_ERROR for an empty adapter, or narrow the docstring to the exception path it actually handles.
Found in the re-review of #260 — the #262 fix covers the reported case but not the one its own docstring claims.
Ontologies.lookup's docstring saysADAPTER_ERRORmeans "the lookup could not be performed at all — a failed semsql download, an empty sqlite stub, an OAK change."It does not cover the stub.
ADAPTER_ERRORis returned only whenget_adapteroradapter.labelraises. A 0-byte or schema-only sqlite opens without error and returnslabel() == Nonefor every id, so every pair falls through toUNRESOLVED— exactly the failure #262 described: the committed TSVs silently rewritten to ~1200 rows that read as a catastrophic corpus finding, exiting 0.The wording is the more dangerous half, because it tells the next reader the case is handled.
scripts/validate_id_label_correspondence.pyseparatesLOAD_FAILEDfromEMPTY_ADAPTERfor this reason, and its_is_emptyis an O(1) probe —next(iter(adapter.entities()), None) is None, with a positive stub confirmation if the probe itself raises, so a partially-migrated live ontology is not masked.Fix: mirror that probe at adapter-open time and return
ADAPTER_ERRORfor an empty adapter, or narrow the docstring to the exception path it actually handles.