Your GraphQL call returned 200 OK but nothing saved? It was throttled
Your GraphQL mutation returned 200 OK. Your code logged success. But the inventory update never happened. This is the most deceptive failure in cost-based GraphQL APIs: a throttle that arrives as a 200, not a 429.
Why 200 is a lie here
Shopify Admin GraphQL and GitHub GraphQL limit by calculated query cost, not request count. When you exceed the budget, they don't return 429 — they return HTTP 200 with an errors array: Shopify {code: THROTTLED} with a throttleStatus, GitHub {type: RATE_LIMITED}. Because the HTTP status is 200, status-code-only retry logic records it as a success — some clients even reset their circuit breaker on it. The result: the throttle is never retried and the data is silently lost.
GitHub's docs warn verbatim that continuing to make requests while rate-limited can get your integration banned. And a GraphQL RATE_LIMITED 200 recorded as "success" doesn't just fail — it can actively clear a circuit breaker that other calls depend on. [tag: false-success]
Detect it: parse the body, not the status
- Shopify: check
errors[].extensions.code === "THROTTLED"and readextensions.cost.throttleStatus. On mutations also inspectuserErrors, not just top-levelerrors. - GitHub: check
errors[].type === "RATE_LIMITED"for the primary limit (5000 points/hour/user), and watch for a secondary-limit body message ("you have exceeded a secondary rate limit") on 403/429.
Compute the wait — don't blind-retry
Throttling triggers on requested cost (computed before execution), so retrying immediately fails again. Shopify: wait ≈ (requestedQueryCost − currentlyAvailable) / restoreRate seconds. GitHub primary: wait until x-ratelimit-reset; secondary: honor retry-after or back off exponentially with jitter. Better still, reduce the query cost (fewer fields/connections, smaller pages) so it fits the bucket, and self-throttle when currentlyAvailable is low.
Snapback's ecommerce family catches both — pass the 200-with-THROTTLED / RATE_LIMITED response to diagnose_infra_error and it returns the compute-the-wait fix.
Machine-readable guide: https://snapback.sh/llms.txt · Tool discovery: https://snapback.sh/.well-known/mcp.json · MCP endpoint: https://api.snapback.sh/mcp. Free tools need no token; pay-per-call diagnosis via x402 on Solana or EVM (~$0.0032 USDC).