Skip to content

SDK drift: fetchArbitrage/fetch_arbitrage — explicit-null marketA/marketB produce different types (object vs None) #1699

Description

@realfishsam

Drift

When a server payload has an explicit null for marketA/marketB, TypeScript's r.marketA || {} fallback still produces a fully-shaped (if empty) UnifiedMarket object via convertMarket({}). Python's _parse_market returns its input unchanged when it's neither a UnifiedMarket nor a dict, so r.get("marketA", {}) — which only substitutes the default when the key is absent, not when it's null — lets an explicit null flow straight through as None.

TypeScript SDK

sdks/typescript/pmxt/router.ts:615-616:

marketA: convertMarket(r.marketA || {}),
marketB: convertMarket(r.marketB || {}),

Python SDK

sdks/python/pmxt/router.py:642-643:

market_a=_parse_market(r.get("marketA", {})),
market_b=_parse_market(r.get("marketB", {})),

_parse_market (sdks/python/pmxt/router.py:28-34) returns its input unchanged when it's neither a UnifiedMarket nor a dict.

Expected

Both SDKs should produce the same type for market_a/market_b given the same wire payload — either both fall back to an empty market object, or both preserve None.

Impact

ArbitrageOpportunity.market_a/market_b is None in Python vs. a market-shaped object in TypeScript for the same payload. Any code doing opportunity.market_a.title crashes with AttributeError in Python but not in TypeScript. This is distinct from existing issue #1535, which is scoped to numeric/venue field defaulting on this same method, not the market-object type itself.


Found by automated SDK cross-language drift audit

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions