🔧 Troubleshooting & Fixes

Hyperliquid Python SDK: KeyError Instead of ClientError on Some 4xx Responses (2026)

⚠️ Disclosure: Some links on this page are affiliate links. If you sign up through them, I may earn a commission — at no extra cost to you. I only review tools I actually use.
As of 2026-11-14, GitHub issue #342 reports that the Hyperliquid Python SDK's API._handle_exception can raise KeyError: 'code' instead of ClientError when a 4xx HTTP response has a JSON body that does not include code or msg. The issue is open in the public repository and identifies SDK version 0.24.0, commit 2fdb18f9517675ea03695a0962bd19eece9c83f0, as the reported environment.

What the reported failure looks like

The issue describes a 4xx response with a JSON body such as:

{"error": "something"}

In that case, the reported code path calls err.get("data") and then unconditionally accesses err["code"] and err["msg"]. If the JSON body has neither key, the caller receives KeyError: 'code' instead of the expected ClientError.

That matters for bots that use:

except ClientError:
    # handle Hyperliquid API error

Because KeyError is not a ClientError, the reported exception can bypass that handler and crash the process on an error path.

Affected code path

The issue points to hyperliquid/api.py:30-41 as the root-cause location. The reported condition is:

The issue also notes a control case: a body that includes code and msg raises ClientError correctly. A plain-text 4xx body is reported to take another branch and raise ClientError properly.

Reproduction from the issue

The issue includes a unit-test reproduction that does not require a server:

from hyperliquid.api import API

class FakeResp:
    status_code = 400
    text = '{"error": "something"}'
    headers = {}

API()._handle_exception(FakeResp())  # reported to raise KeyError('code')

This is a reference reproduction from the public issue, not an author-run test.

The reporter also noted that an invalid /info type on testnet returned HTTP 422 with a plain-text body in their probes, which takes the other branch and raises ClientError properly. The KeyError branch needs a 4xx JSON body without code or msg, which the reporter's testnet probes did not produce.

💡 Hyperliquid

Like what you're reading? Try it yourself — this link supports ChartedTrader at no cost to you.

Create a Hyperliquid account →
🎁 You receive: 4% fee discount on first $25M volume · per account, lifetime

Suggested fix

The issue suggests using safe dictionary access with fallbacks to the raw body, rather than direct indexing:

code = err.get("code") or "unknown"
msg = err.get("msg") or resp.text
# Raise the SDK's ClientError using code and msg.

This is a reference patch concept from the issue, not a verified official SDK change. Check the repository for a merged fix before applying a local patch.

Practical workaround until the SDK is patched

If your code depends on ClientError for all API error handling, the reported KeyError path can still escape. A defensive workaround is to catch the broader exception while logging enough context to distinguish the SDK error-shape issue from a normal application error:

try:
    # Replace with the Hyperliquid SDK call you are making.
    api_call()
except KeyError as exc:
    if str(exc) == "'code'":
        print("Hyperliquid SDK raised KeyError('code') on a 4xx response; see issue #342")
    raise

This does not make the SDK behave as documented; it only logs the reported exception before re-raising it. Treat the reporter's safety assessment—that the exception propagates loudly, nothing is silently reported as success, and no wrong trade can result—as an unverified issue-report assessment, not a guarantee of safe execution.

How this fits Hyperliquid API error responses

The official Hyperliquid error-response documentation describes order and cancel errors, including batched responses. It notes that order and cancel errors are usually returned as a vector with the same length as the batched request, while some deterministic payload errors are returned earlier as pre-validation and produce one error for the entire payload.

For SDK users, that means two separate layers matter:

  1. The API response payload may contain order/cancel error objects or a single pre-validation error.
  2. The SDK's exception handler must convert that response into the expected Python exception.
The GitHub issue is about the second layer: the SDK exception conversion can raise KeyError for some 4xx JSON bodies.

References

Affiliate CTA

The Hyperliquid link below is an affiliate link. The site may earn a commission if you sign up. The referral benefit is a 4% fee discount on the first $25M of volume per account; Vaults and sub-accounts are excluded.

Create a Hyperliquid account

Continue with Hyperliquid

Continue with the Hyperliquid Python SDK tutorial for a broader bot-building reference, or browse the Hyperliquid guide hub for the complete user journey.

🧮 Free Hyperliquid calculators

Fee Calculator →
Hyperliquid vs centralized exchange fee comparison
PnL & Liquidation →
Perp PnL + liquidation price
Position Size →
Risk-aware position sizing for HL perps
Hyperliquid

Ready to get started? Use the link below — it helps support ChartedTrader at no cost to you.

Create a Hyperliquid account →
🎁 You receive: 4% fee discount on first $25M volume · per account, lifetime
📈

About the author

I'm a systematic trader running live strategies on IB (USDJPY momentum) and Hyperliquid (crypto perps). Every tool reviewed here is something I've used with real capital. Questions? Reach out.

📚 Related Articles

🔧
Troubleshooting & Fixes

Hyperliquid Spot Meta Array Mismatch Fix (2026)

Hyperliquid spotMetaAndAssetCtxs returns 320 assets while your code expects 711? Here is why the array length mismatch happens and how to make the Python SDK resilient.

August 24, 2026 ⏱ 11 min read
🔌
API & Developers

Hyperliquid Python SDK Tutorial: Build a Bot (2026)

Build a production-ready trading bot on Hyperliquid using the official Python SDK. Covers API wallet security, order execution, WebSocket feeds, and common pitfalls to avoid.

May 6, 2026 ⏱ 12 min read
🔌
API & Developers

Hyperliquid candleSnapshot Timestamps and Completion: Community-Reported Observations

Community-reported Hyperliquid candleSnapshot behavior: t/T are Unix milliseconds, T is inclusive, no completion flag, and older requests can return an empty 200 response.

November 15, 2026 ⏱ 3 min read