Shopify Diagnostics
Shopify-specific recipes for debugging the Shopify app integration. For general ecommerce diagnostics (jobs, logs, S3, search proxy), see Ecommerce Platform.
Querying Shopify GraphQL Directly
Check variant metafield definitions
Shopify Admin UI: Settings > Custom data > Variants
Query variant metafields via API
curl -s -X POST \
-H 'Content-Type: application/json' \
-H 'X-Shopify-Access-Token: <access-token>' \
-d '{
"query": "{ products(first: 1) { edges { node { title variants(first: 3) { edges { node { id title metafields(first: 20) { edges { node { namespace key value type } } } } } } } } } }"
}' \
'https://<store>.myshopify.com/admin/api/2024-10/graphql.json'
Query specific variants by ID
Simulates the enrichment query used during bulk sync:
curl -s -X POST \
-H 'Content-Type: application/json' \
-H 'X-Shopify-Access-Token: <access-token>' \
-d '{
"query": "query($ids: [ID!]!) { nodes(ids: $ids) { ... on ProductVariant { id inventoryItem { inventoryLevels(first: 50) { edges { node { location { id name } quantities(names: [\"available\"]) { name quantity } } } } } metafields(first: 250) { edges { node { namespace key value type } } } } } }",
"variables": { "ids": ["gid://shopify/ProductVariant/<id1>", "gid://shopify/ProductVariant/<id2>"] }
}' \
'https://<store>.myshopify.com/admin/api/2024-10/graphql.json'
Using the helper script
The scripts/ecom/shopify_graphql.py script handles access token retrieval
from DynamoDB automatically:
# Simple shop info query
python scripts/ecom/shopify_graphql.py \
--shop cool-store.myshopify.com --env prod --profile controller \
--query '{ shop { name } }'
# Query with variables
python scripts/ecom/shopify_graphql.py \
--shop cool-store.myshopify.com --env prod --profile controller \
--query '{ products(first: 1) { edges { node { id title publishedAt } } } }'
# Query from file
python scripts/ecom/shopify_graphql.py \
--shop cool-store.myshopify.com --env prod --profile controller \
--query-file queries/products.graphql \
--variables '{"ids": ["gid://shopify/ProductVariant/123"]}'
The core functions (get_shopify_access_token, shopify_graphql) can also be
imported by other scripts for programmatic use.
Where to find access tokens
- Helper script:
scripts/ecom/shopify_graphql.pyretrieves tokens automatically from DynamoDB - DynamoDB:
prod-ShopifyEntitiesTableper-user session records for the shop (pk = SHOP#{shop_domain},sk = USER#{user_id}) - Shopify Admin UI: Settings > Apps and sales channels > Develop apps
Metafield Debugging
How metafield field names are generated
Metafields are transformed into camelCase Marqo field names:
product_metafield + custom + season → productMetafieldCustomSeason
variant_metafield + custom + web_filters_gender → variantMetafieldCustomWebFiltersGender
See Shopify Metafield Indexing for full pipeline documentation.
Common metafield issues
| Symptom | Likely Cause |
|---|---|
Processed 0 variant metafields in logs | Expected for bulk sync — variant metafields come from the enrichment step, not the JSONL |
| Variant metafield fields missing on docs | Metafield definitions don't exist on the Shopify store, or no values are populated on variants |
| Metafield values are nested lists | The metafield type is list.single_line_text_field — values should be flattened during aggregation |
Verifying metafields in S3 documents
aws s3 cp "s3://{env}-ecom-product-data-bucket/<shop-id>//bulk/<job-id>/chunk_0000.jsonl" - \
--profile <profile> | python3 -c "
import sys, json
for line in sys.stdin:
doc = json.loads(line)
title = doc.get('variantTitle', '?')
mf = {k: v for k, v in doc.items() if 'metafield' in k.lower()}
print(f'=== {title} ===')
for k, v in sorted(mf.items()):
print(f' {k}: {v}')
print()
"
Bulk Export Constraints
The Shopify bulk export query (BULK_EXPORT_ALL_PRODUCTS) is at the 5-connection limit. Current connections:
products(top-level)variantsmediacollectionsmetafields(product-level only)
Variant metafields cannot be added to the bulk export. They are fetched via a separate enrichment query (GET_VARIANT_ENRICHMENT_DATA) that runs after transformation, alongside per-location inventory.