Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
40rty-ai avatar

Shopify Admin Compare At Price Cleanup

  • 2 installs
  • 173 repo stars
  • Updated June 26, 2026
  • 40rty-ai/shopify-admin-skills

shopify-admin-compare-at-price-cleanup is a Claude Code skill that removes stale compareAtPrice values where the current price is no lower than the compare-at price or the compare-at price has aged past a threshold.

About

This skill finds Shopify variants whose compareAtPrice no longer represents a genuine discount, either because the current price meets or exceeds it or because it has been set past a configurable age threshold, and clears those values. Merchants use it so storefront strikethrough pricing reflects real savings. It defaults to dry_run and writes an audit CSV on every run.

  • Clears stale compareAtPrice values where price >= compareAtPrice (no real discount)
  • Also clears compareAtPrice older than a configurable age threshold
  • Defaults to dry_run and always writes an audit CSV for revert

Shopify Admin Compare At Price Cleanup by the numbers

  • 2 all-time installs (skills.sh)
  • Ranked #1,839 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
  • Data as of Aug 1, 2026 (Skillselion catalog sync)
At a glance

shopify-admin-compare-at-price-cleanup capabilities & compatibility

Free skill; requires an authenticated Shopify store session with read_products and write_products scopes.

Capabilities
price cleanup · pricing hygiene · variant bulk update · csv export
Works with
stripe
Use cases
data analysis
Pricing
Bring your own API key
From the docs

What shopify-admin-compare-at-price-cleanup says it does

Removes stale compareAtPrice values where current price >= compareAtPrice (no real discount) or compareAtPrice has been set for over a configurable age threshold.
SKILL.md
so storefront strikethrough pricing reflects real savings rather than legacy noise
SKILL.md
npx skills add https://github.com/40rty-ai/shopify-admin-skills --skill shopify-admin-compare-at-price-cleanup

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs2
repo stars173
Last updatedJune 26, 2026
Repository40rty-ai/shopify-admin-skills

What it does

Clear stale or fake Shopify compare-at prices so strikethrough pricing reflects genuine discounts.

Who is it for?

Merchants who want strikethrough pricing to reflect real savings and avoid always-on-sale optics.

Skip if: Setting new sale prices; it only clears compareAtPrice values that no longer represent a discount.

When should I use this skill?

You want to remove leftover or perpetual compare-at prices that show a fake discount.

What you get

Variants with no-discount or stale compare-at prices have those values cleared, with an audit CSV for revert.

  • Variants with stale compareAtPrice cleared
  • audit CSV of affected variants written on every run

By the numbers

  • default max_age_days 90 for the stale rule
  • paginates variants 250 per request
  • batches mutations by product id

Files

SKILL.mdMarkdownGitHub ↗

Purpose

Identifies variants with a compareAtPrice that no longer represents a genuine discount and clears it, so storefront strikethrough pricing reflects real savings rather than legacy noise. Two conditions are flagged: (a) compareAtPrice <= price (no discount, often left over from a price increase), and (b) compareAtPrice set for longer than max_age_days (stale "always on sale" optics that hurt long-term price perception and can violate advertising standards in some regions). Defaults to dry-run.

Prerequisites

  • Authenticated Shopify CLI session: shopify store auth --store <domain> --scopes read_products,write_products
  • API scopes: read_products, write_products

Parameters

ParameterTypeRequiredDefaultDescription
storestringyesStore domain (e.g., mystore.myshopify.com)
dry_runboolnotruePreview the cleanup without executing mutations
clean_no_discountboolnotrueClear compareAtPrice when price >= compareAtPrice
clean_staleboolnotrueClear compareAtPrice set longer than max_age_days
max_age_daysintegerno90Age threshold in days for the stale rule (uses variant updatedAt as proxy)
collection_idstringnoOptional collection GID to scope the cleanup
tag_filterstringnoOptional product tag to scope the cleanup
formatstringnohumanOutput format: human or json

Safety

⚠️ Step 2 executes productVariantsBulkUpdate mutations that overwrite compareAtPrice to null. The original strikethrough value is not preserved server-side — record the dry-run CSV before committing if you want a restore path. Always start with dry_run: true and review the CSV before running with dry_run: false.

Workflow Steps

1. OPERATION: productVariants — query Inputs: first: 250, query: <built from collection_id or tag_filter>, select price, compareAtPrice, updatedAt, product { id, title, vendor }, sku, pagination cursor Expected output: All variants in scope with current pricing; paginate until hasNextPage: false

2. Filter to variants meeting either rule: clean_no_discount AND compareAtPrice != null AND parseFloat(compareAtPrice) <= parseFloat(price), OR clean_stale AND compareAtPrice != null AND (now - updatedAt) > max_age_days. Group by product.id for batched mutation.

3. OPERATION: productVariantsBulkUpdate — mutation (skipped when dry_run: true) Inputs: Per product, productId plus [{ id: variantId, compareAtPrice: null }] Expected output: Updated variants with compareAtPrice set to null; collect userErrors per batch

4. Write the CSV (always, even on dry run) for audit trail and revert capability.

GraphQL Operations

# productVariants:query — validated against api_version 2025-01
query VariantsForCompareAtCleanup($query: String, $after: String) {
  productVariants(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        sku
        price
        compareAtPrice
        updatedAt
        product {
          id
          title
          vendor
          tags
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
# productVariantsBulkUpdate:mutation — validated against api_version 2025-01
mutation ClearCompareAtPrice($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
  productVariantsBulkUpdate(productId: $productId, variants: $variants) {
    productVariants {
      id
      price
      compareAtPrice
    }
    userErrors {
      field
      message
    }
  }
}

Session Tracking

Claude MUST emit the following output at each stage. This is mandatory.

On start, emit:

╔══════════════════════════════════════════════╗
║  SKILL: Compare-At Price Cleanup             ║
║  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):

══════════════════════════════════════════════
COMPARE-AT PRICE CLEANUP  (<dry-run|live>)
  Variants inspected:      <n>
  No-discount cleared:     <n>
  Stale (>= <days>d):      <n>
  Total cleared:           <n>
  Errors:                  <n>
  Output: compare_at_cleanup_<date>.csv
══════════════════════════════════════════════

For format: json, emit:

{
  "skill": "compare-at-price-cleanup",
  "store": "<domain>",
  "dry_run": true,
  "variants_inspected": 0,
  "cleared_no_discount": 0,
  "cleared_stale": 0,
  "total_cleared": 0,
  "errors": 0,
  "output_file": "compare_at_cleanup_<date>.csv"
}

Output Format

CSV file compare_at_cleanup_<YYYY-MM-DD>.csv with columns: variant_id, product_id, product_title, vendor, sku, price, original_compare_at_price, rule_matched, variant_updated_at, mutation_status

Error Handling

ErrorCauseRecovery
userErrors in mutation responseVariant locked or in active subscription contractLog per-variant error, continue with remaining variants
THROTTLEDAPI rate limit exceededWait 2 seconds, retry up to 3 times
compareAtPrice already null mid-runAnother process cleared it concurrentlySkip, count as no-op success
updatedAt newer than expectedConcurrent edit during the auditRe-query single variant before mutation; skip if rule no longer matches

Best Practices

1. Always run with dry_run: true first and review the CSV. There is no bulk undo for compareAtPrice clearing. 2. Disable clean_stale (set clean_stale: false) during long planned promotions — your "stale" sale is actually intentional. 3. Use collection_id to scope the cleanup to evergreen products and exclude an active sale collection. 4. After running live, spot-check 5–10 variants in the storefront to confirm strikethrough pricing is gone. 5. Schedule a quarterly run as part of catalog hygiene; combine with seo-metadata-audit and product-data-completeness-score for an end-of-quarter merchandising sweep.

Related skills

FAQ

Which compare-at prices does it clear?

Those where price >= compareAtPrice (no real discount) and, optionally, those set longer than max_age_days (default 90), using the variant updatedAt as a proxy.

Is the change reversible?

The original strikethrough value is not preserved server-side, so it writes a CSV on every run (including dry runs) as a restore path; it defaults to dry_run:true.

Automation & Workflowsecommercepricing

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.