Gap
MyriadExchange registers its implicit API from core/src/exchanges/myriad/api.ts via defineImplicitApi(parseOpenApiSpec(myriadApiSpec, ...)) (core/src/exchanges/myriad/index.ts:43-44). Myriad's spec declares no operationId fields, so parseOpenApiSpec/generateMethodName (core/src/utils/openapi.ts:15-24) auto-derives a method name from the HTTP verb + path, filtering out path-param segments (anything starting with {):
function generateMethodName(httpMethod: string, path: string): string {
const segments = path.split('/').filter(s => s && !s.startsWith('{'));
const pascalPath = segments.map(toPascalCase).join('');
return httpMethod.toLowerCase() + pascalPath;
}
Because path-param segments are stripped, both a collection endpoint and a single-item endpoint at the same base path generate the identical method name:
GET /questions → getQuestions
GET /questions/{id} → getQuestions (collision)
GET /markets → getMarkets
GET /markets/{id} → getMarkets (collision)
parseOpenApiSpec (core/src/utils/openapi.ts:72-79) writes endpoints[name] = {...} for each path in Object.entries(spec.paths) iteration order, so the later-declared path silently overwrites the earlier one in the resulting map. In core/src/exchanges/myriad/api.ts, /questions is declared at line 43 and /questions/{id} at line 88; /markets at line 103 and /markets/{id} at line 237. Since the single-item variants are declared after the collection variants, the final method bound to getQuestions is GET /questions/{id}, and the final method bound to getMarkets is GET /markets/{id}. The bare collection endpoints (GET /questions, GET /markets) become permanently unreachable under their natural generated names — there is no other implicit method name that reaches them.
Core
core/src/exchanges/myriad/api.ts:43,88,103,237 (path declarations) and core/src/utils/openapi.ts:15-24,72-79 (generateMethodName/parseOpenApiSpec, the root-cause collision logic). MyriadExchange's own fetchRawOHLCV/fetchRawOrderBook happen to call callApi('getMarkets', ...) expecting the single-market lookup (core/src/exchanges/myriad/index.ts), which works only because the single-item endpoint happens to win the collision — this is incidental, not by design.
TypeScript SDK
Missing — sdks/typescript/pmxt/client.ts's callApi(operationId, params) (line 755) is a fully generic passthrough to whatever implicit-API method name core registers under. Because core itself never binds a reachable name to the bare GET /questions / GET /markets endpoints, no SDK-side fix is possible without a core change; there is no wrapper method (typed or untyped) that reaches these two endpoints.
Python SDK
Missing — sdks/python/pmxt/client.py's call_api(operation_id, params) (line 1226) has the identical generic-passthrough limitation for the same reason.
Evidence
Verified directly: grep -n '"/questions"\|"/questions/{id}"\|"/markets"\|"/markets/{id}"' core/src/exchanges/myriad/api.ts shows declaration order /questions (43) → /questions/{id} (88) → /markets (103) → /markets/{id} (237); grep -c operationId core/src/exchanges/myriad/api.ts returns 0, confirming no explicit operationIds exist to disambiguate. Since JS object key assignment in parseOpenApiSpec overwrites on collision, the last writer per name wins.
Impact
Any SDK consumer calling myriadClient.callApi('getQuestions') or callApi('getMarkets') expecting a plain collection listing will silently receive the single-item endpoint's behavior instead (a 404/validation error, or in the worst case a subtly wrong single-record response if a stray id-shaped param is present) — with no way to reach the actual list endpoint through the generated implicit API in either SDK. This is invisible until someone tries it: has/implicitApi introspection reports a method named getQuestions/getMarkets exists, but it is bound to the wrong operation.
Found by automated Core-to-SDK surface coverage audit
Gap
MyriadExchangeregisters its implicit API fromcore/src/exchanges/myriad/api.tsviadefineImplicitApi(parseOpenApiSpec(myriadApiSpec, ...))(core/src/exchanges/myriad/index.ts:43-44). Myriad's spec declares nooperationIdfields, soparseOpenApiSpec/generateMethodName(core/src/utils/openapi.ts:15-24) auto-derives a method name from the HTTP verb + path, filtering out path-param segments (anything starting with{):Because path-param segments are stripped, both a collection endpoint and a single-item endpoint at the same base path generate the identical method name:
GET /questions→getQuestionsGET /questions/{id}→getQuestions(collision)GET /markets→getMarketsGET /markets/{id}→getMarkets(collision)parseOpenApiSpec(core/src/utils/openapi.ts:72-79) writesendpoints[name] = {...}for each path inObject.entries(spec.paths)iteration order, so the later-declared path silently overwrites the earlier one in the resulting map. Incore/src/exchanges/myriad/api.ts,/questionsis declared at line 43 and/questions/{id}at line 88;/marketsat line 103 and/markets/{id}at line 237. Since the single-item variants are declared after the collection variants, the final method bound togetQuestionsisGET /questions/{id}, and the final method bound togetMarketsisGET /markets/{id}. The bare collection endpoints (GET /questions,GET /markets) become permanently unreachable under their natural generated names — there is no other implicit method name that reaches them.Core
core/src/exchanges/myriad/api.ts:43,88,103,237(path declarations) andcore/src/utils/openapi.ts:15-24,72-79(generateMethodName/parseOpenApiSpec, the root-cause collision logic).MyriadExchange's ownfetchRawOHLCV/fetchRawOrderBookhappen to callcallApi('getMarkets', ...)expecting the single-market lookup (core/src/exchanges/myriad/index.ts), which works only because the single-item endpoint happens to win the collision — this is incidental, not by design.TypeScript SDK
Missing —
sdks/typescript/pmxt/client.ts'scallApi(operationId, params)(line 755) is a fully generic passthrough to whatever implicit-API method name core registers under. Because core itself never binds a reachable name to the bareGET /questions/GET /marketsendpoints, no SDK-side fix is possible without a core change; there is no wrapper method (typed or untyped) that reaches these two endpoints.Python SDK
Missing —
sdks/python/pmxt/client.py'scall_api(operation_id, params)(line 1226) has the identical generic-passthrough limitation for the same reason.Evidence
Verified directly:
grep -n '"/questions"\|"/questions/{id}"\|"/markets"\|"/markets/{id}"' core/src/exchanges/myriad/api.tsshows declaration order/questions(43) →/questions/{id}(88) →/markets(103) →/markets/{id}(237);grep -c operationId core/src/exchanges/myriad/api.tsreturns 0, confirming no explicitoperationIds exist to disambiguate. Since JS object key assignment inparseOpenApiSpecoverwrites on collision, the last writer per name wins.Impact
Any SDK consumer calling
myriadClient.callApi('getQuestions')orcallApi('getMarkets')expecting a plain collection listing will silently receive the single-item endpoint's behavior instead (a 404/validation error, or in the worst case a subtly wrong single-record response if a strayid-shaped param is present) — with no way to reach the actual list endpoint through the generated implicit API in either SDK. This is invisible until someone tries it:has/implicitApiintrospection reports a method namedgetQuestions/getMarketsexists, but it is bound to the wrong operation.Found by automated Core-to-SDK surface coverage audit