Polymarket’s Python SDK story has two active tracks in August 2026. The official docs now recommend the unified py-sdk — published to PyPI as polymarket-client, at v0.5.0 since August 7 and out of the beta phase we covered in the May tracker — for new projects, while the transitional py-clob-client-v2 (v1.1.0, July 17) remains maintained and widely deployed. The health gap between them is stark: py-sdk has just five open issues, only one of them a bug (its May-era reports are no longer on the open list), while py-clob-client-v2 carries 60 open issues.
This brief documents the six significant issues we verified open as of August 12, 2026 — including the long-awaited root-cause finding for the deposit-wallet rejections that have dogged the V2 line since the CLOB V2 cutover. It continues our April and May trackers. Every section gives the exact symptom, the root cause as documented in the issue thread, and a workaround.
Every issue below was open with no maintainer fix merged as of August 12, 2026. Where a mitigation comes from the issue thread rather than a confirmed fix, we label it a suggestion.
The deposit-wallet mystery, solved: V2 requires ERC-7739 nested signing the SDK cannot produce
- py-clob-client-v2 #111 — opened August 10, 2026, against v1.1.0.
This is the most important Polymarket SDK issue of the year. For months, developers hit the same wall we documented in April and May:
maker address not allowed, please use the deposit wallet flow
Authentication succeeds (GET /auth returns fine), then POST /order fails in every signature mode the Python SDK offers — which made it look like an auth bug. Issue #111 shows it isn’t. The production V2 exchange requires the deposit-wallet flow, which means three things at once:
fundermust be a deployed deposit-wallet contract, not the EOA.- Authentication must use
signature_type=3(POLY_1271). - Order signatures must be ERC-7739 nested
TypedDataSignwrapped, so the deposit wallet’s on-chainisValidSignaturecan verify them.
The Python SDK has no ERC-7739 wrapping capability at all — so every wallet mode it provides is structurally incompatible with placing orders on production V2. The reporter proved it with a controlled test on the same EOA key: the Python SDK (signature types 0 and 2+proxy) authenticates but has its orders rejected, while the Rust SDK (POLY_1271 with a deployed deposit wallet) both authenticates and trades successfully.
Workaround: There is no Python-side fix you can apply — the missing piece is a signing scheme, not a parameter. Until the suggested fix lands (implementing SignatureType.POLY_1271 with ERC-7739 nested wrapping, with rs-clob-client-v2 named in the thread as the reference implementation), trade deposit-wallet accounts through the Rust SDK or the Polymarket UI. See the POLY_1271 smart-contract wallet guide for how the flow is supposed to work.
py-sdk silently discards failed partial fills (fund-safety bug)
- py-sdk #266 — opened August 12, 2026, against
polymarket-client0.5.0.
When a market order generates multiple fills and some of them fail on-chain (gas issues, reverts), wait_for_order_fill_settlement() returns only the successful transaction hashes — no error, no warning, no mention of the fills that failed.
The root cause is in _collect_settlement_hashes() in settlement.py: it raises TransactionFailedError only when all trades fail —
if trades and all(_is_failed_trade(trade) for trade in trades):
raise TransactionFailedError(...)
— so as long as one fill succeeds, the failed trades are dropped without their IDs ever reaching the caller. The issue author calls this what it is: a silent fund-loss scenario. Your bot believes an order settled cleanly when part of it never executed.
Workaround (suggested): The thread’s proposed fix — raise whenever any fill fails — hasn’t merged. Until it does, never treat the returned hash list as the full picture of a multi-fill order. Reconcile against your actual position after settlement:
# py-sdk #266: settlement can silently drop failed fills.
# Verify what you actually hold via the Data API after every multi-fill order.
import requests
def actual_position(address, token_id):
resp = requests.get(
f"https://data-api.polymarket.com/positions?user={address}"
)
for p in resp.json():
if p["asset"] == token_id:
return float(p["size"])
return 0.0
# Compare against the size you believe settled; alert on any shortfall.
L2 HMAC signs Python’s False/None instead of JSON false/null
- py-clob-client-v2 #108 — opened August 5, 2026.
build_hmac_signature serializes non-string bodies with str(body).replace("'", '"'). That trick works for dicts of plain strings, but Python’s str() renders booleans and null as False/True/None — not the JSON false/true/null the server sees. So signing the dict {"deferExec": False} produces a different HMAC than signing json.dumps({"deferExec": False}), and the request fails L2 authentication.
Internal SDK callers mostly dodge this by passing a pre-serialized body, but the helper is exported publicly, and create_level_2_headers falls back to the raw dict when serialized_body is omitted — which is exactly when the mismatch bites.
Workaround: Serialize the body yourself and hand the SDK the exact string you send:
# py-clob-client-v2 #108: str(body) renders False/None, not false/null.
# json.dumps the body and pass it as serialized_body so the HMAC
# is computed over the same bytes the server verifies.
import json
body = {"deferExec": False}
serialized = json.dumps(body) # '{"deferExec": false}'
# ...pass serialized as serialized_body when building L2 headers,
# and send exactly that string as the request body.
The thread proposes the obvious fix — serialize non-string bodies with json.dumps and add boolean/null regression tests — and links PR #109, unmerged as of this writing. See auth troubleshooting for distinguishing this from other L2 header failures.
GET /fee-rate returns a constant 1000 for every fee-bearing market
- py-clob-client-v2 #107 — opened August 4, 2026.
Fee-aware bots have been computing fees from a value that isn’t a fee rate. The reporter tested three markets with documented rates of 4%, 5%, and 7% — and GET /fee-rate returned the identical "base_fee":1000 for all of them. The evidence in the thread points to base_fee being a binary “this market has fees” flag, not a rate in basis points. The real per-category rate lives in the fd.r field of GET /clob-markets/{condition_id}, where the values match the documented schedule exactly: crypto 0.07, sports 0.05, finance 0.04, geopolitics 0 — and fd: null correctly marks fee-free markets.
The SDK makes it worse: get_fee_rate_bps() populates its __fee_rates cache from the broken /fee-rate endpoint, and __resolve_fee_rate_bps() uses that cached value when signing v1 orders — even though the SDK separately caches the correct rates in __fee_infos. v2 orders pass fee_rate_bps=None and sidestep the whole problem.
Workaround: Don’t trust /fee-rate for anything beyond “fees exist here.” Read fd.r from the market payload for the actual rate, and prefer the v2 order path:
# py-clob-client-v2 #107: base_fee=1000 is a has-fees flag, not a rate.
# The real per-category rate is fd.r on the market object.
fd = market.get("fd") # from GET /clob-markets/{condition_id}
real_rate = 0.0 if fd is None else float(fd["r"]) # e.g. 0.07 = crypto
The thread also flags open questions for maintainers — the semantics of fd.e, and whether the sports rate quietly moved from 0.03 to 0.05 — with no maintainer response yet.
POLY_PROXY is broken end to end: balances read as zero, orders rejected as invalid
Two issues combine to make signature_type=1 (POLY_PROXY — Magic/email-derived proxy wallets) effectively unusable from Python.
py-clob-client-v2 #105 — opened August 1, 2026, against v1.1.0.
get_balance_allowance()returns{"balance": "0", "allowance": "0"}for a proxy wallet verifiably holding $111+ in pUSD. The reporter traced it: the request the SDK builds contains onlysignature_type(plus optionalasset_type/token_id) — the funder/proxy address is never included in the request, and thesignature_typefield declared onBalanceAllowanceParamsis never even read. The API has no way to know which wallet you’re asking about. This mirrors the earlier deposit-wallet (POLY_1271) reports #64, #70, and #77.py-clob-client-v2 #104 — opened July 22, 2026. The same account class can’t place orders either. A Magic.link-derived proxy account that trades fine through the Polymarket UI gets rejected on every SDK path, with a payload the reporter documented as identical (maker, signer, signatureType) to a working UI order:
invalid POLY_PROXY signature
Routing the same account through POLY_1271 instead returns the order signer address has to be the address of the API KEY (the familiar May-tracker error), and falling back to the v1 client returns invalid order version, please use the latest clob-client. Notably, get_balance_allowance() authenticates fine with POLY_PROXY — the failure is specific to order-signature validation.
Workaround: For balances (#105), skip the SDK and read the chain — call balanceOf(funder) on the pUSD contract with web3.py, as the reporter did (see the get_balance_allowance guide for the on-chain pattern). For orders (#104), no workaround exists in the thread — the reporter’s request for a known-good POLY_PROXY flow has gone unanswered. Trade these accounts through the UI until the signature validation is fixed. Given #111 above, the deposit-wallet flow is likely where these accounts end up anyway.
Defensive patterns for August 2026
- Know your wallet type before you write code. If your account requires the deposit-wallet flow, no amount of Python-side debugging fixes #111 — plan on the Rust SDK or the UI.
- Reconcile every multi-fill settlement. Until py-sdk #266 is fixed, compare the position you hold (Data API) against what you believe settled. Alert on shortfalls; don’t trust the hash list.
- Pre-serialize L2 bodies. Any dict body containing a boolean or
Nonemust go throughjson.dumpsbefore signing (#108). - Never read fees from
/fee-rate. Treatbase_feeas a boolean and pull the real rate fromfd.r(#107) — a 1000-bps assumption will wreck your edge calculations on every fee-bearing market. - Verify balances on-chain for proxy wallets.
get_balance_allowance()is blind to the funder address for POLY_PROXY (#105);balanceOfdoesn’t lie.
Summary table
| Issue | SDK | Symptom | Workaround |
|---|---|---|---|
| #111 | py-clob-client-v2 | Orders rejected: maker address not allowed, please use the deposit wallet flow — SDK can’t produce required ERC-7739 nested signatures | Rust SDK or UI for deposit-wallet accounts; no Python-side fix |
| #266 | py-sdk | wait_for_order_fill_settlement returns only successful hashes; failed partial fills silently dropped | Reconcile position via Data API after every multi-fill order |
| #108 | py-clob-client-v2 | Dict bodies with False/None produce wrong L2 HMAC → auth failure | json.dumps the body yourself; pass serialized_body |
| #107 | py-clob-client-v2 | GET /fee-rate returns constant base_fee: 1000 on all fee-bearing markets | Read the real rate from fd.r on the market object; prefer v2 orders |
| #105 | py-clob-client-v2 | get_balance_allowance() returns 0/0 for POLY_PROXY — funder address never sent | Query balanceOf on the pUSD contract on-chain |
| #104 | py-clob-client-v2 | POLY_PROXY orders rejected: invalid POLY_PROXY signature (identical payload works in UI) | None in thread — use the UI for these accounts |
Further reading
- py-clob-client-v2 Bug Tracker (April 2026) — the V1 archive and the first V2 bug cluster
- Polymarket Beta SDK Bugs (May 2026) — the py-sdk/ts-sdk beta issues, most now resolved
- Top 10 Polymarket API Problems — the recurring integration failures, conceptually
- py-clob-client Reference — Python client methods and known issues
- py_clob_client get_balance_allowance() Guide — balance checking, including the on-chain fallback
- py-clob-client-v2 Errors — decode the V2 client’s error messages
- Polymarket CLOB V2 Migration — what changed at the April 28, 2026 cutover
- POLY_1271 Smart-Contract Wallets — how deposit-wallet signing is supposed to work
- Polymarket Rust SDK Reference — the only client that handles the deposit-wallet flow today
- Polymarket Auth Troubleshooting — fix POLY header and signature errors
- Polymarket API Tutorial — full API walkthrough
- Official SDK docs — Polymarket’s current client recommendations
