
Shopify Admin Variant Option Normalizer
- 7 installs
- 173 repo stars
- Updated June 26, 2026
- 40rty-ai/shopify-admin-skills
shopify-admin-variant-option-normalizer is a Claude Code skill that detects inconsistent variant option naming and bulk-corrects it to a standard set.
About
A Claude Code skill that scans Shopify product variants for inconsistent option values and bulk-updates them to a canonical set defined by a mapping. It fixes issues where inconsistent naming breaks size filters and variant grouping. It defaults to dry-run so affected variants can be reviewed before committing.
- Detects inconsistent variant option values (Sm vs Small vs S) against a mapping
- Bulk-updates variants to canonical values via productVariantsBulkUpdate
- Dry-run by default; fixes broken size filters and variant grouping
Shopify Admin Variant Option Normalizer by the numbers
- 7 all-time installs (skills.sh)
- Ranked #1,587 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 1, 2026 (Skillselion catalog sync)
shopify-admin-variant-option-normalizer capabilities & compatibility
Free; requires an authenticated Shopify CLI session with write_products.
- Capabilities
- variant normalization · catalog cleanup · bulk update
- Runs
- Runs locally
- Pricing
- Free
What shopify-admin-variant-option-normalizer says it does
Detects inconsistent variant option naming (Sm vs Small vs S) and bulk-corrects to a standard set.
Inconsistent option naming breaks size filters, causes customer confusion, and prevents search apps from grouping variants correctly.
npx skills add https://github.com/40rty-ai/shopify-admin-skills --skill shopify-admin-variant-option-normalizerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 7 |
|---|---|
| repo stars | ★ 173 |
| Last updated | June 26, 2026 |
| Repository | 40rty-ai/shopify-admin-skills ↗ |
What it does
Normalize inconsistent Shopify variant option values to a canonical set in bulk.
Who is it for?
Merchants cleaning up size or color option values that were entered inconsistently.
Skip if: Renaming the option itself or restructuring products; it only normalizes values.
When should I use this skill?
Size or color filters break because option values like Sm, Small, and S are mixed.
What you get
Variant option values normalized to a canonical set with a change-log CSV.
- option_normalizer_<date>.csv
- Bulk variant option updates
By the numbers
- 2 GraphQL operations (products query + productVariantsBulkUpdate mutation)
- dry_run defaults to true
Files
Purpose
Scans product variants for inconsistent option values (e.g., "Sm", "Small", "small", "S" all meaning the same size) and bulk-updates them to a canonical set you define. Inconsistent option naming breaks size filters, causes customer confusion, and prevents search apps from grouping variants correctly.
Prerequisites
- Authenticated Shopify CLI session:
shopify store auth --store <domain> --scopes read_products,write_products - API scopes:
read_products,write_products
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| option_name | string | yes | — | Option to normalize (e.g., Size, Color) |
| mapping | object | yes | — | Map of non-standard → canonical values (e.g., {"Sm": "S", "small": "S", "Sml": "S"}) |
| filter | string | no | — | Optional product filter (e.g., tag:apparel) |
| dry_run | bool | no | true | Preview changes without executing mutations |
| format | string | no | human | Output format: human or json |
Safety
⚠️productVariantsBulkUpdatemodifies variant option values. Option value changes affect how the variant appears to customers in the storefront and may break existing cart links or saved wishlists. Run withdry_run: trueto review all affected variants before committing.
Workflow Steps
1. OPERATION: products — query Inputs: query: <filter> (or all products if no filter), first: 250, select options, variants { selectedOptions }, pagination cursor Expected output: Products with variant option values; paginate until hasNextPage: false
2. Match variant option values against mapping keys — collect variants needing update
3. OPERATION: productVariantsBulkUpdate — mutation Inputs: productId, array of variants { id, options: [<normalized_value>] } for affected variants Expected output: productVariants { id, selectedOptions }, userErrors
GraphQL Operations
# products:query — validated against api_version 2025-01
query ProductVariantOptions($query: String!, $after: String) {
products(first: 250, after: $after, query: $query) {
edges {
node {
id
title
options {
id
name
values
}
variants(first: 100) {
edges {
node {
id
title
sku
selectedOptions {
name
value
}
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}# productVariantsBulkUpdate:mutation — validated against api_version 2025-01
mutation ProductVariantsBulkUpdate($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
productVariantsBulkUpdate(productId: $productId, variants: $variants) {
productVariants {
id
title
selectedOptions {
name
value
}
}
userErrors {
field
message
}
}
}Session Tracking
Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║ SKILL: Variant Option Normalizer ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝After each step, emit:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>If dry_run: true, prefix every mutation step with [DRY RUN] and do not execute it.
On completion, emit:
For format: human (default):
══════════════════════════════════════════════
OUTCOME SUMMARY
Products scanned: <n>
Variants needing fix: <n>
Variants updated: <n>
Errors: <n>
Output: option_normalizer_<date>.csv
══════════════════════════════════════════════For format: json, emit:
{
"skill": "variant-option-normalizer",
"store": "<domain>",
"started_at": "<ISO8601>",
"completed_at": "<ISO8601>",
"dry_run": true,
"option_name": "Size",
"outcome": {
"products_scanned": 0,
"variants_needing_fix": 0,
"variants_updated": 0,
"errors": 0,
"output_file": "option_normalizer_<date>.csv"
}
}Output Format
CSV file option_normalizer_<YYYY-MM-DD>.csv with columns: product_id, product_title, variant_id, sku, option_name, old_value, new_value
Error Handling
| Error | Cause | Recovery |
|---|---|---|
THROTTLED | API rate limit exceeded | Wait 2 seconds, retry up to 3 times |
userErrors on bulk update | Option value conflict within product | Log error, skip product, continue |
| No matching variants | Mapping keys not found in catalog | Exit with 0 matches, review mapping |
Best Practices
- Build the
mappingby first running withdry_run: trueand reviewing the detected option values — you may discover more variants than expected. - Normalize one
option_nameat a time (Size, then Color separately) to keep the mapping manageable and reduce error risk. - After normalizing, verify that automated collection rules based on option values still match the intended products.
Related skills
FAQ
Will it change how variants appear to customers?
Yes, so it defaults to dry_run so you can review affected variants first.
How does it know the canonical value?
You supply a mapping of non-standard to canonical values.