Summary
OgcApiEndpoint.csapiCollections crashes with TypeError: Cannot read properties of null (reading 'collections') when the endpoint's landing page does not advertise a link with rel: "data" (or its long-URI variant). Five sibling collection getters share the same bug pattern.
The crash is triggered by a real, conformant CSAPI server: the OpenSensorHub demo (http://45.55.99.236:8080/sensorhub/api) cited in PR #136's own validation list.
Reproduction
import { OgcApiEndpoint } from '@camptocamp/ogc-client';
const endpoint = new OgcApiEndpoint('http://45.55.99.236:8080/sensorhub/api');
console.log(await endpoint.hasConnectedSystems); // true (correct)
console.log(await endpoint.csapiCollections); // ❌ throws
Stack trace:
TypeError: Cannot read properties of null (reading 'collections')
at parseCollections (dist/dist-node.js:2873:14)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
Root cause
Two interacting issues:
1. csapiCollections doesn't null-check data (the immediate crash)
src/ogc-api/endpoint.ts:230-236:
get csapiCollections(): Promise<string[]> {
return Promise.all([this.data, this.hasConnectedSystems])
.then(([data, hasCSAPI]) => (hasCSAPI ? data : { collections: [] }))
.then(parseCollections) // ← parseCollections(null) throws
...
Compare to the sibling allCollections, which correctly null-checks before calling parseCollections:
return this.data.then((dataDocument) =>
dataDocument ? parseCollections(dataDocument) : []
);
The same null-deref pattern is present in 5 other getters sharing the Promise.all([this.data, this.hasX]).then(...).then(parseCollections) shape:
| Line |
Getter |
| 187 |
recordCollections |
| 198 |
featureCollections |
| 206 |
edrCollections |
| 244 |
vectorTileCollections |
| 257 |
mapTileCollections |
2. Why data is null here (separate concern, broader fix)
collectionsUrl only follows links with rel: "data" or http://www.opengis.net/def/rel/ogc/1.0/data. OpenSensorHub's landing page uses rel: "collections" instead:
{
"rel": "collections",
"title": "Collections available on this server",
"href": "http://45.55.99.236:8080/sensorhub/api/collections",
"type": "application/json"
}
So collectionsUrl resolves to null, data resolves to null, and every dependent getter then crashes.
OGC API Common Part 2 specifies data as the canonical rel — OpenSensorHub is technically out of spec — but rel: "collections" is widely seen in the wild, and after the immediate null-deref is fixed, the library still won't discover any collections from these servers. Worth considering whether collectionsUrl should additionally accept rel: "collections" for compatibility.
Proposed fix
Minimum (unblocks the crash, no behavior change)
Mirror the allCollections null-guard in all six affected getters. Single-token edit per getter:
- .then(([data, hasCSAPI]) => (hasCSAPI ? data : { collections: [] }))
+ .then(([data, hasCSAPI]) => (hasCSAPI && data ? data : { collections: [] }))
I've applied this to csapiCollections locally and verified the OpenSensorHub case now returns { hasConnectedSystems: true, collections: [] } cleanly (instead of crashing). The same diff applied to the other 5 getters would make them robust by symmetry.
Recommended (also fixes the empty-collections downstream issue)
Additionally, accept rel: "collections" in collectionsUrl:
- ['data', 'http://www.opengis.net/def/rel/ogc/1.0/data'],
+ ['data', 'http://www.opengis.net/def/rel/ogc/1.0/data', 'collections'],
This is a pragmatic compatibility win for OpenSensorHub-style servers; happy to defer to maintainers on whether this belongs here vs. being treated as a server-conformance issue.
Why this matters / context
I'm building a Python ADK agent (Google Gemini) that uses @camptocamp/ogc-client/csapi via a Node CLI subprocess to query CSAPI endpoints from natural language. This is the second consumer of the library beyond ogc-csapi-explorer, so the bug surfaced immediately when probing the public test servers cited in PR #136.
Cross-references:
Environment
- Node
v24.15.0, npm 11.12.1
- Snapshot:
OS4CSAPI/ogc-client-CSAPI_2 phase-7 branch
- Built locally with
npm run build
- Probed against OpenSensorHub on 2026-05-03
Narasimha Sharma Narayanam (@nsnarayanam )
Summary
OgcApiEndpoint.csapiCollectionscrashes withTypeError: Cannot read properties of null (reading 'collections')when the endpoint's landing page does not advertise a link withrel: "data"(or its long-URI variant). Five sibling collection getters share the same bug pattern.The crash is triggered by a real, conformant CSAPI server: the OpenSensorHub demo (
http://45.55.99.236:8080/sensorhub/api) cited in PR #136's own validation list.Reproduction
Stack trace:
Root cause
Two interacting issues:
1.
csapiCollectionsdoesn't null-checkdata(the immediate crash)src/ogc-api/endpoint.ts:230-236:Compare to the sibling
allCollections, which correctly null-checks before callingparseCollections:The same null-deref pattern is present in 5 other getters sharing the
Promise.all([this.data, this.hasX]).then(...).then(parseCollections)shape:recordCollectionsfeatureCollectionsedrCollectionsvectorTileCollectionsmapTileCollections2. Why
datais null here (separate concern, broader fix)collectionsUrlonly follows links withrel: "data"orhttp://www.opengis.net/def/rel/ogc/1.0/data. OpenSensorHub's landing page usesrel: "collections"instead:{ "rel": "collections", "title": "Collections available on this server", "href": "http://45.55.99.236:8080/sensorhub/api/collections", "type": "application/json" }So
collectionsUrlresolves tonull,dataresolves tonull, and every dependent getter then crashes.OGC API Common Part 2 specifies
dataas the canonical rel — OpenSensorHub is technically out of spec — butrel: "collections"is widely seen in the wild, and after the immediate null-deref is fixed, the library still won't discover any collections from these servers. Worth considering whethercollectionsUrlshould additionally acceptrel: "collections"for compatibility.Proposed fix
Minimum (unblocks the crash, no behavior change)
Mirror the
allCollectionsnull-guard in all six affected getters. Single-token edit per getter:I've applied this to
csapiCollectionslocally and verified the OpenSensorHub case now returns{ hasConnectedSystems: true, collections: [] }cleanly (instead of crashing). The same diff applied to the other 5 getters would make them robust by symmetry.Recommended (also fixes the empty-collections downstream issue)
Additionally, accept
rel: "collections"incollectionsUrl:This is a pragmatic compatibility win for OpenSensorHub-style servers; happy to defer to maintainers on whether this belongs here vs. being treated as a server-conformance issue.
Why this matters / context
I'm building a Python ADK agent (Google Gemini) that uses
@camptocamp/ogc-client/csapivia a Node CLI subprocess to query CSAPI endpoints from natural language. This is the second consumer of the library beyondogc-csapi-explorer, so the bug surfaced immediately when probing the public test servers cited in PR #136.Cross-references:
csa.demo.52north.org) is also broken in a separate way — its/conformanceno longer declares any CSAPI URI, sohasConnectedSystemscorrectly returnsfalse. Probably a server-side regression worth flagging to that team.Environment
v24.15.0, npm11.12.1OS4CSAPI/ogc-client-CSAPI_2phase-7branchnpm run buildNarasimha Sharma Narayanam (@nsnarayanam )