Skip to main content

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.py retrieves tokens automatically from DynamoDB
  • DynamoDB: prod-ShopifyEntitiesTable per-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

SymptomLikely Cause
Processed 0 variant metafields in logsExpected for bulk sync — variant metafields come from the enrichment step, not the JSONL
Variant metafield fields missing on docsMetafield definitions don't exist on the Shopify store, or no values are populated on variants
Metafield values are nested listsThe 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:

  1. products (top-level)
  2. variants
  3. media
  4. collections
  5. metafields (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.