Skip to content

CcxtBroker[hyperliquid]: fetchMarkets(hip3) fails with "Invalid response body #403

Description

@cyrilfaia-dot

The Hyperliquid CCXT broker integration in
@traderalice/uta-service stops fetching markets and goes offline
after fetchMarkets(hip3) returns an "Invalid response body" error
8 times in a row. The upstream Hyperliquid API is fully operational
at the same time, so the failure appears to be on the hip3 (HIP-3
permissionless markets) parsing path inside the CCXT wrapper.

Environment

  • OpenAlice: 0.60.0-beta.1 (HEAD f331859,
    v0.60.0-beta.1-12-gf331859)
  • @traderalice/uta-service: 0.1.0
  • ccxt: ^4.5.38 (from services/uta/package.json)
  • Node: v26.4.0
  • OS: macOS 26.4 (Darwin 25.4.0, arm64)
  • Broker entry: hyperliquid-017169f9 (CCXT-backed, tier: trading)

Steps to reproduce

alice-uta account list

In the returned JSON, locate the Hyperliquid broker entry and
inspect its health block.

Expected behavior

The broker entry reports health.status: "healthy", reach: "connected", and a recent lastSuccessAt timestamp. Subsequent
calls (alice-uta account info, account portfolio, contract details, etc.) succeed.

Actual behavior

The broker entry remains in offline state with recovering: true
and the following error repeating on every reconnection attempt:

CcxtBroker[hyperliquid-017169f9]: fetchMarkets(hip3) failed after 8
attempts: Invalid response body while trying to fetch
https://api.hyperliquid.xyz/info: aborted

The condition has persisted for ~4h+ at the time of writing.
consecutiveFailures stays pinned at 6. No other broker
(binance-readonly, okx-readonly, bybit-readonly) is affected.

Diagnostic already done

The Hyperliquid API itself is fully responsive — this is
reproducible from the same machine:

  1. Direct POST against the failing endpoint (Hyperliquid's
    /info is a POST endpoint; a GET correctly returns 405):

    curl -sS -X POST -H "Content-Type: application/json" \
         -d '{"type":"meta"}' https://api.hyperliquid.xyz/info \
         -w "\nHTTP %{http_code}  bytes=%{size_download}\n"

    Returns HTTP 200 with ~17 KB of valid JSON containing the full
    perp universe (BTC, ETH, SOL, …). So the host, TLS, and standard
    /info schema are all fine.

  2. Hyperliquid public status page (hyperliquid.statuspage.io)
    reports: "All systems operational. 100% uptime over the past 90
    days. No incidents reported today."
    The only recent maintenance was
    a network upgrade completed 2026-06-27 08:45 UTC, ~22 h before
    lastSuccessAt, so likely unrelated.

  3. Failure is specific to the hip3 request type. The error
    string is fetchMarkets(hip3) — distinct from fetchMarkets() for
    the standard perp universe (which the {"type":"meta"} test above
    proves is still served correctly). HIP-3 is the more recent
    "permissionless markets" listing.

Hypotheses (in decreasing order of likelihood)

  1. Hyperliquid changed the response schema or pagination shape of
    the HIP-3 markets endpoint (the request type Alice's ccxt wrapper
    calls for hip3), and the version of ccxt pinned at ^4.5.38 no
    longer parses it cleanly.
  2. The hip3 endpoint returns an intermittently malformed response
    (truncated / aborted before the JSON closes), and the wrapper does
    not retry-then-fallback to standard meta markets.
  3. The CCXT wrapper inside @traderalice/uta-service calls
    fetchMarkets("hip3") (or equivalent) at boot/reconnect with no
    graceful degradation when HIP-3 fails — so a single endpoint
    regression takes the entire broker offline, including BTC/ETH perps
    that don't depend on HIP-3.

Impact

  • The affected broker account is fully unusable: no account info,
    no portfolio, no quotes, no orders, no git status.
  • Any strategy running in supervised auto mode against this
    broker is blocked at its first step (kill-switch check / pre-cycle
    git status) and cannot proceed even to publish a "no setup" report
    — only the wrapping schedule's offline handler can surface
    anything.
  • The failure mode is all-or-nothing: there is no degraded
    read-only operation, and standard perps (BTC, ETH) that don't need
    HIP-3 metadata are inaccessible too.
  • recovering: true suggests the wrapper will keep retrying
    indefinitely; no operator action will recover it as long as the
    upstream hip3 payload stays in its current shape.

Logs / traces

All timestamps UTC. Reproducer machine is the same throughout.

Time Source Event
2026-06-28T06:34:44Z health.lastSuccessAt Last
successful broker call
2026-06-28T09:14:18Z health.lastFailureAt (observed)
Failures already accumulated; consecutiveFailures: 6
2026-06-28T09:40:27Z health.lastFailureAt (observed)
Same error, still offline, still recovering: true
2026-06-28T10:24:58Z health.lastFailureAt (observed)
Same error, ~3 h 50 min after lastSuccessAt

Verbatim health block returned by alice-uta account list at
2026-06-28T10:24Z:

{
  "id": "hyperliquid-017169f9",
  "label": "HYPE",
  "capabilities": {
    "supportedSecTypes": ["CRYPTO", "CRYPTO_PERP"],
    "supportedOrderTypes": ["MKT", "LMT"],
    "historicalBars": { "supported": true, "quality": "realtime" }
  },
  "health": {
    "status": "offline",
    "reach": "down",
    "tier": "trading",
    "consecutiveFailures": 6,
    "lastError": "CcxtBroker[hyperliquid-017169f9]:
fetchMarkets(hip3) failed after 8 attempts: Invalid response body
while trying to fetch https://api.hyperliquid.xyz/info: aborted",
    "lastSuccessAt": "2026-06-28T06:34:44.487Z",
    "lastFailureAt": "2026-06-28T10:24:58.235Z",
    "recovering": true,
    "disabled": false
  }
}

Other brokers in the same account list snapshot
(binance-readonly, okx-readonly, bybit-readonly) were all
healthy / connected with fresh lastSuccessAt values, ruling
out a local network or general CCXT regression.

Direct upstream confirmation, same machine, ~10:46 UTC:

$ curl -sS -X POST -H "Content-Type: application/json" \
       -d '{"type":"meta"}' https://api.hyperliquid.xyz/info \
       -w "\nHTTP %{http_code}  bytes=%{size_download}
time=%{time_total}s\n"
{"universe":[{"szDecimals":5,"name":"BTC","maxLeverage":40,...},
...]}
HTTP 200  bytes=17326  time=0.489103s

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