From shopify-pack
Diagnoses common Shopify API errors (401, 403, 422, 429, GraphQL) with real responses, causes, and fixes like curl tests and scope reconfiguration.
How this skill is triggered — by the user, by Claude, or both
Slash command
/shopify-pack:shopify-common-errorsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Quick-reference guide for the most common Shopify API errors with real error messages, causes, and fixes.
Quick-reference guide for the most common Shopify API errors with real error messages, causes, and fixes.
Check whether the error is an HTTP status code error or a GraphQL userErrors response.
Actual Shopify Response:
{
"errors": "[API] Invalid API key or access token (unrecognized login or wrong password)"
}
Causes:
X-Shopify-Access-Token headerFix:
# Verify token format:
# Admin API token: shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 hex chars)
# Storefront API token: different format, starts with shpat_ too
curl -s -o /dev/null -w "%{http_code}" \
-H "X-Shopify-Access-Token: $SHOPIFY_ACCESS_TOKEN" \
"https://your-store.myshopify.com/admin/api/2024-10/shop.json"
# Should return 200
Actual Shopify Response:
{
"errors": "This action requires merchant approval for read_orders scope."
}
Cause: Your app's access token lacks the required scope.
Fix: Add the needed scope to your app config and re-trigger OAuth:
# shopify.app.toml
[access_scopes]
scopes = "read_products,write_products,read_orders,write_orders"
Actual Shopify Response:
{
"errors": "Not Found"
}
Causes:
Fix:
# Verify the API version exists
curl -s "https://your-store.myshopify.com/admin/api/2024-10/shop.json" \
-H "X-Shopify-Access-Token: $TOKEN"
# Check available API versions
curl -s "https://your-store.myshopify.com/admin/api/versions.json" \
-H "X-Shopify-Access-Token: $TOKEN"
Actual Shopify Responses:
{
"errors": {
"title": ["can't be blank"],
"handle": ["has already been taken"]
}
}
{
"errors": {
"base": ["Product cannot be saved: Title is too long (maximum is 255 characters)"]
}
}
Common 422 triggers:
Fix: Check the errors object or userErrors array for specific field-level messages.
REST API Response:
HTTP/1.1 429 Too Many Requests
Retry-After: 2.0
GraphQL Response (in body, returns 200):
{
"errors": [
{
"message": "Throttled",
"extensions": {
"code": "THROTTLED",
"documentation": "https://shopify.dev/api/usage/rate-limits"
}
}
],
"extensions": {
"cost": {
"requestedQueryCost": 752,
"actualQueryCost": null,
"throttleStatus": {
"maximumAvailable": 2000,
"currentlyAvailable": 0,
"restoreRate": 100
}
}
}
}
Fix: See shopify-rate-limits skill for complete backoff implementation.
Critical: Shopify returns HTTP 200 even when mutations fail.
{
"data": {
"productCreate": {
"product": null,
"userErrors": [
{
"field": ["title"],
"message": "Title can't be blank",
"code": "BLANK"
}
]
}
}
}
Always check userErrors after every mutation:
const response = await client.request(mutation, { variables });
const result = response.data.productCreate;
if (result.userErrors.length > 0) {
// These are validation errors, NOT HTTP errors
for (const err of result.userErrors) {
console.error(`Field ${err.field?.join(".")}: ${err.message} (${err.code})`);
}
throw new Error("Shopify validation failed");
}
Shopify internal errors — not your fault, but you must handle them.
{
"errors": "Internal Server Error"
}
Fix: Retry with exponential backoff. Include the X-Request-Id header value when reporting to Shopify support.
// The X-Request-Id header is in every Shopify response
const requestId = error.response?.headers?.["x-request-id"];
console.error(`Shopify 500 error. Request ID: ${requestId}`);
| Status | Name | Retryable | Action |
|---|---|---|---|
| 401 | Unauthorized | No | Re-authenticate, verify token |
| 403 | Forbidden | No | Add missing scope, re-OAuth |
| 404 | Not Found | No | Check URL, API version, resource ID |
| 422 | Unprocessable | No | Fix validation errors in request body |
| 429 | Throttled | Yes | Backoff using Retry-After header |
| 500 | Server Error | Yes | Retry with backoff, report X-Request-Id |
| 503 | Unavailable | Yes | Shopify is overloaded, retry later |
#!/bin/bash
STORE="your-store.myshopify.com"
TOKEN="$SHOPIFY_ACCESS_TOKEN"
VERSION="2024-10"
echo "=== Shopify Diagnostic ==="
# 1. Test auth
echo -n "Auth: "
curl -s -o /dev/null -w "%{http_code}" \
-H "X-Shopify-Access-Token: $TOKEN" \
"https://$STORE/admin/api/$VERSION/shop.json"
echo ""
# 2. Check scopes
echo "Scopes:"
curl -s -H "X-Shopify-Access-Token: $TOKEN" \
"https://$STORE/admin/oauth/access_scopes.json" | python3 -m json.tool
# 3. Check API versions
echo "API Versions:"
curl -s -H "X-Shopify-Access-Token: $TOKEN" \
"https://$STORE/admin/api/versions.json" | python3 -c "
import json, sys
versions = json.load(sys.stdin)['supported_versions']
for v in versions[:5]:
print(f' {v[\"handle\"]} {\"(latest)\" if v.get(\"latest\") else \"\"}')"
# 4. Shopify status
echo "Shopify Status: https://www.shopifystatus.com"
For comprehensive debugging, see shopify-debug-bundle.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin shopify-packIdentifies Shopify API anti-patterns like ignoring userErrors, outdated versions, REST over GraphQL, missing GDPR webhooks, and timeouts. Reviews code with real examples.
Use Shopify GraphQL Admin API for server CRUD on products/orders and Storefront API for client queries on products/cart, with versioning, rate limits, bulk ops, pagination.
Provides Shopify CLI commands and operational steps for validating app/extension config, running store workflows, inventory/product operations, and CLI setup/auth/upgrade troubleshooting.