<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arvio</title>
    <description>The latest articles on DEV Community by Arvio (@arvio).</description>
    <link>https://dev.to/arvio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4093045%2F1f6cad86-b3ce-49f5-8493-6b46ac75c184.png</url>
      <title>DEV Community: Arvio</title>
      <link>https://dev.to/arvio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arvio"/>
    <language>en</language>
    <item>
      <title>AI agent for ecommerce: there are two different jobs, and the search results only show you one</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Sun, 27 Sep 2026 05:04:03 +0000</pubDate>
      <link>https://dev.to/arvio/ai-agent-for-ecommerce-there-are-two-different-jobs-and-the-search-results-only-show-you-one-49oi</link>
      <guid>https://dev.to/arvio/ai-agent-for-ecommerce-there-are-two-different-jobs-and-the-search-results-only-show-you-one-49oi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/ai-agent-for-ecommerce?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/ai-agent-for-ecommerce&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Published September 27, 2026 by &lt;a href="https://apps.shopify.com/partners/adot-inc?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_listing1" rel="noopener noreferrer"&gt;Adot Technologies Inc&lt;/a&gt;, the team behind Arvio. Vendor figures were read on September 27, 2026 from the vendors' own homepages; catalogue figures come from public storefront endpoints any browser can fetch. Method, sample and what we could not read are all below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this post is and isn't.&lt;/strong&gt; It is not a ranked list of the best AI agents, and it is not a feature scorecard — we did not sign up for any of these products or run them against each other. What we did is narrower and checkable: we opened the homepage of every site on Google's first page for this search and counted which kind of work each one advertises. That tells you which aisle you are standing in. It does not tell you what any of these products can actually do. There is a section near the end on when the right answer is a support tool and not us.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two-minute version: which aisle are you in?
&lt;/h2&gt;

&lt;p&gt;Before you compare anything, answer one question about your own store. Write your answer down, then read the table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the last month, what cost you the most — questions you didn't answer, or products you didn't fix?&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If the thing that hurts is…&lt;/th&gt;
&lt;th&gt;The agent you want does…&lt;/th&gt;
&lt;th&gt;What it reads&lt;/th&gt;
&lt;th&gt;Homepages on the first page advertising that work&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shoppers asking "where's my order", "does this fit", "can I return it" and nobody replying for 9 hours&lt;/td&gt;
&lt;td&gt;Conversations: inbox, live chat, tickets, handoff to a human&lt;/td&gt;
&lt;td&gt;Your help docs, order records, the chat transcript&lt;/td&gt;
&lt;td&gt;7 of the 9 we could read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A size that sold out three weeks ago and is still on the page as available&lt;/td&gt;
&lt;td&gt;Records: the product, variant, price and inventory objects themselves&lt;/td&gt;
&lt;td&gt;Your catalogue, one product row at a time&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0 of the 9&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;td&gt;Two tools. These do not substitute for each other&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That zero is the finding. Not one of the nine readable homepages used any of eighteen phrases about editing a product, updating inventory, adjusting a price, managing a catalogue or running a campaign — including the one-word needle &lt;code&gt;seo&lt;/code&gt;, which is the easiest phrase in that list to hit by accident.&lt;/p&gt;

&lt;p&gt;The other two of the nine aren't in the conversation column either: one is a platform for building your own agents, and one matched neither list. Details and the full table are two sections down.&lt;/p&gt;

&lt;p&gt;If your problem is the first row, a catalogue tool will not touch it — install a support agent and stop reading comparison posts. If it's the second row, the conversation tools in the first row are not a smaller version of what you need; they are pointed at a different object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the second row on your own store, in about a minute
&lt;/h2&gt;

&lt;p&gt;This is the part nobody is selling you, so here is how to look at it yourself. It needs no install and no command-line tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open this in a browser tab&lt;/strong&gt;, replacing the domain with your own storefront:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-store.com/products.json?limit=250
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most Shopify storefronts serve that publicly. You will get a wall of JSON. Don't read it — search it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then press Ctrl-F (⌘F on a Mac) and search for this exact string — the quotes matter, and there is no space after the colon:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"available"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser's find bar will tell you how many times it occurs. That count is the number of &lt;strong&gt;variants&lt;/strong&gt; currently out of stock across the products on that page — every size, colour and bundle option that has gone to zero. For comparison, search &lt;code&gt;"available":true&lt;/code&gt; the same way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two things about that URL before you read anything into the number.&lt;/strong&gt; &lt;code&gt;limit=250&lt;/code&gt; is a hard ceiling: if you have more than 250 products you are only looking at the first 250, and you need &lt;code&gt;&amp;amp;page=2&lt;/code&gt;, &lt;code&gt;&amp;amp;page=3&lt;/code&gt; and so on to see the rest. And the raw count scales with catalogue size, so it means little on its own — on two large public catalogues we searched while checking these instructions, 250 products returned 602 and 1,973 out-of-stock variants. Those are big, healthy stores. The number is a prompt, not a verdict.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the count means, and what it doesn't.&lt;/strong&gt; A high &lt;code&gt;false&lt;/code&gt; count on its own is not a problem — a product where &lt;em&gt;every&lt;/em&gt; variant is false is a fully sold-out product, which is a different (and more visible) issue we have written about separately. The state worth hunting is the mixed one: a product where some variants are false and some are true, because that product is still live, still looks available, and quietly cannot fulfil the size the shopper wants. Ctrl-F alone cannot separate the two, so treat the number as a prompt to go look, not as a measurement.&lt;/p&gt;

&lt;p&gt;To see an actual example, don't try to scroll — the file is usually one enormous single line, so there is nothing to scroll up through. Instead search for &lt;code&gt;"handle":&lt;/code&gt;, which appears exactly once per product. Step through those hits and open any handle on your storefront as &lt;code&gt;your-store.com/products/THE-HANDLE&lt;/code&gt;, then see whether the page tells a shopper anything is missing. (Searching &lt;code&gt;"title":&lt;/code&gt; does not work for this: variant names use the same key, so it fires several times per product.)&lt;/p&gt;

&lt;p&gt;If you want the exact mixed-state percentage rather than a prompt, that needs a script rather than a find bar — it has to group variants by their parent product and count the products where at least one variant is false and at least one is true. That is the measure behind the &lt;strong&gt;15.3%&lt;/strong&gt; below, and it is exactly the kind of counting nobody does by hand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Two jobs, two tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvio is an AI store operator — it works on the record side of the store, not the conversation side. What it does and does not touch is spelled out on our App Store listing rather than here, because this post is about the split, not about us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=ai-agent-for-ecommerce&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What we actually measured, and what it does not prove
&lt;/h2&gt;

&lt;p&gt;Read this before the table, because the table is easy to over-read.&lt;/p&gt;

&lt;p&gt;On 27 September 2026 at 11:56 we took the ten domains ranking on Google's first page for &lt;code&gt;ai agent for ecommerce&lt;/code&gt;, opened each homepage in a real browser, and pulled &lt;code&gt;document.body.innerText&lt;/code&gt;. Then we searched that text for three fixed lists of phrases: 18 describing work on store records (&lt;code&gt;edit product&lt;/code&gt;, &lt;code&gt;update inventory&lt;/code&gt;, &lt;code&gt;adjust price&lt;/code&gt;, &lt;code&gt;manage catalog&lt;/code&gt;, &lt;code&gt;bulk edit&lt;/code&gt;, &lt;code&gt;seo&lt;/code&gt;, &lt;code&gt;ad campaign&lt;/code&gt; and eleven more), 16 describing work on customer conversations (&lt;code&gt;live chat&lt;/code&gt;, &lt;code&gt;support ticket&lt;/code&gt;, &lt;code&gt;help desk&lt;/code&gt;, &lt;code&gt;resolution rate&lt;/code&gt;, &lt;code&gt;shared inbox&lt;/code&gt;, &lt;code&gt;abandoned cart&lt;/code&gt;, &lt;code&gt;product recommendation&lt;/code&gt; and nine more), and 10 describing tooling for building your own agent (&lt;code&gt;no-code&lt;/code&gt;, &lt;code&gt;agent builder&lt;/code&gt;, &lt;code&gt;drag-and-drop&lt;/code&gt;, &lt;code&gt;build your own&lt;/code&gt; and six more).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This measures what each company advertises on its own front page. It does not measure what the product can do.&lt;/strong&gt; A homepage is a marketing page. A vendor whose homepage never mentions inventory may still have an inventory feature two clicks away, and a vendor matching &lt;code&gt;customer service&lt;/code&gt; twelve times may do a great deal more than chat. Everything below is a claim about copy, and it is phrased that way on purpose. If you want to know whether one of these products edits your catalogue, ask them — this post is not evidence either way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nine of ten, not ten of ten.&lt;/strong&gt; One of the ten domains did not return a page to us on this run: the browser reported a closed connection and a plain HTTPS retry failed at the TLS layer. We could not read it, so it is excluded from every count and percentage below — it is not counted as a zero in any column. &lt;strong&gt;Nine is the denominator throughout.&lt;/strong&gt; We're leaving it unnamed because a domain failing to load on one afternoon says something about that afternoon, not about the company. A blank is not a zero, and "not readable" is its own bucket rather than a rounding convenience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How a page gets sorted into a bucket.&lt;/strong&gt; Zero record-work phrases on all nine, so that column never decided anything. Between the other two, the rule is relative weight, not mere presence: a page is called a builder only if it matched &lt;em&gt;more&lt;/em&gt; builder phrases than conversation phrases. That distinction matters and we got it wrong the first time — an early version flagged any page containing a builder phrase, which classified Tidio as a builder platform on the strength of two matches for its own drag-and-drop automation feature, against nine matches about support. A feature named "visual automation builder" is not a company describing itself as a builder platform. Under the relative rule it sorts as a conversation tool, which is plainly what its own page title says it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the nine readable homepages advertise
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Homepage, as read on 27 September 2026&lt;/th&gt;
&lt;th&gt;Its own page title&lt;/th&gt;
&lt;th&gt;Record-work phrases&lt;/th&gt;
&lt;th&gt;Conversation phrases&lt;/th&gt;
&lt;th&gt;Builder phrases&lt;/th&gt;
&lt;th&gt;Bucket&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;delight.ai&lt;/td&gt;
&lt;td&gt;Delight AI: AI concierge for stellar customer experiences&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tidio.com&lt;/td&gt;
&lt;td&gt;AI Customer Service That Turns Chats Into Revenue | Tidio&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mindstudio.ai&lt;/td&gt;
&lt;td&gt;Build powerful AI agents | MindStudio&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;builder&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;layer3labs.io&lt;/td&gt;
&lt;td&gt;Layer3Labs - OpenAI, Claude, Gemini for Business&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yourgpt.ai&lt;/td&gt;
&lt;td&gt;YourGPT | AI Agent Platform for Support, Sales &amp;amp; Operations&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;molin.ai&lt;/td&gt;
&lt;td&gt;Molin AI - Cut your customer support by 80% with AI&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;techmonk.io&lt;/td&gt;
&lt;td&gt;TechMonk | Autonomous AI Agents for Customer Engagement&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fin.ai&lt;/td&gt;
&lt;td&gt;Fin. The highest performing Customer Agent&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;conversations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;triplewhale.com&lt;/td&gt;
&lt;td&gt;Triple Whale — Make waves.&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;matched nothing&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(one domain)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;em&gt;not readable&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;not readable&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;not readable&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;excluded&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;0 of 9 record work. 7 of 9 conversations. 1 builder. 1 that matched none of the 44 phrases.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One row deserves a note rather than a silent pass. &lt;strong&gt;techmonk.io tied&lt;/strong&gt;, 3 and 3 — the rule needs &lt;em&gt;more&lt;/em&gt; builder phrases than conversation phrases to call something a builder, so a tie stays in the conversation column. Read that row as the weakest classification in the table.&lt;/p&gt;

&lt;p&gt;Several of these pages do describe touching store objects; they just describe it from inside the conversation. Molin's homepage lists "Order updates — Update your customers on their orders" and "Product search — Recommend better products to customers." Tidio's lists "Save abandoned carts" and "Preview carts, check order history." YourGPT's says "A chatbot answers. An agent finishes the job." Note the shape: each one is something done &lt;em&gt;for a shopper who is currently talking to you&lt;/em&gt;. None of them is something done to a product page at 2am when nobody is talking to you at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  The one that matched nothing at all
&lt;/h3&gt;

&lt;p&gt;triplewhale.com returned a full page — 7,844 characters of text, so this is not a short page we failed to read — and none of our 44 phrases appeared anywhere in it. Its title is "Triple Whale — Make waves."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That bucket means our measure did not fit, not that the product does nothing.&lt;/strong&gt; A page can sell something real in vocabulary our three lists were never built to catch — analytics and attribution, for instance, are neither conversations nor catalogue edits, and no phrase in any of our lists would find them. It stays where the data put it. The same goes for mindstudio.ai in the row above, except there the evidence is positive rather than absent: zero conversation phrases against six builder ones, under a page title that says "Build powerful AI agents". It is a place to build an agent, not an agent for a store.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we found in 41 real catalogues
&lt;/h2&gt;

&lt;p&gt;The split above is about how a market describes itself. This section is about whether the record-side job is real work, and it comes from different data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample.&lt;/strong&gt; 41 live Shopify storefronts, 20,604 products, read on 26 August 2026 from &lt;code&gt;/products.json&lt;/code&gt;, taken at random from a public list of stores whose owners had posted their own URL on the Shopify Community's Store Feedback board. Everything here came from endpoints any browser can fetch. Zero stores hit the pagination limit on that run, so nothing large was silently truncated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whether it looks like you.&lt;/strong&gt; Stores that ask for feedback skew newer and smaller, and the biggest distortion is survivorship: domains that no longer serve a catalogue were dropped at the frame stage, so what is left is the set that is still trading.&lt;/p&gt;

&lt;h3&gt;
  
  
  The silent one: a product that is live, and partly gone
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measure, across 41 storefronts&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Products with more than one variant&lt;/td&gt;
&lt;td&gt;7,088 (34.4% of all 20,604)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Of those, products with some variants sold out but not all&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,088 — 15.3%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same figure across all products, multi-variant or not&lt;/td&gt;
&lt;td&gt;5.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stores with at least one such product&lt;/td&gt;
&lt;td&gt;28 of the 39 that had any multi-variant products&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median store's rate, within its multi-variant products&lt;/td&gt;
&lt;td&gt;6.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pooled 15.3% against a median store of 6.2% — a ratio of 2.48 — means a minority of catalogues carry most of it. &lt;strong&gt;Do not read 15.3% as "this is what your store looks like."&lt;/strong&gt; Read it as: this is common enough that it is worth spending one minute checking, and if you are in the heavy group you are much worse than 15.3%.&lt;/p&gt;

&lt;p&gt;We also checked whether the high-rate stores were just tiny stores with three multi-variant products each, where one sold-out size makes a big percentage. They were not: of the stores at or above 15%, &lt;strong&gt;11 had ten or more multi-variant products&lt;/strong&gt; and only 3 had fewer than ten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Four things this data cannot tell you, and we are not going to guess at them:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How many units are left.&lt;/strong&gt; The public endpoint gives each variant a true/false &lt;code&gt;available&lt;/code&gt; flag and no quantity. No "fewer than N in stock" claim can be computed from this, ours included.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What the product page shows the shopper.&lt;/strong&gt; Greyed-out size, or a full sold-out banner? We read the records, not the rendered pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whether those variants were discontinued on purpose.&lt;/strong&gt; No store told us why anything went to zero, and a deliberately retired colourway looks identical here to an oversight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How fast anything is restocked.&lt;/strong&gt; This is a single-day snapshot. There is no before-and-after pair, so nothing about speed can be said.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That first limitation matters for the argument: we can show you that a variant is gone, not that anyone is losing money over it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The other record-side finding: imported products are thinner
&lt;/h3&gt;

&lt;p&gt;Same 41 stores. We grouped products by store and creation date, and treated 20 or more products created by one store on one day as a bulk creation batch — 132 such batches across 20 of the 41 stores, accounting for 53.5% of all products.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field, as returned by &lt;code&gt;/products.json&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Products in a batch of 20+ (n=11,014)&lt;/th&gt;
&lt;th&gt;Everything else (n=9,590)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Empty description&lt;/td&gt;
&lt;td&gt;4.4%&lt;/td&gt;
&lt;td&gt;0.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thin description&lt;/td&gt;
&lt;td&gt;29.7%&lt;/td&gt;
&lt;td&gt;11.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No &lt;code&gt;product_type&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;38.0%&lt;/td&gt;
&lt;td&gt;35.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No tags&lt;/td&gt;
&lt;td&gt;21.6%&lt;/td&gt;
&lt;td&gt;17.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One image or none&lt;/td&gt;
&lt;td&gt;46.4%&lt;/td&gt;
&lt;td&gt;21.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The caveat that kills the obvious headline.&lt;/strong&gt; It is tempting to write "the bigger the import, the dirtier the data," and the data does not support it. We ran the same split at three thresholds, and also cut the products into non-overlapping size bands. In those bands the 20–49 band is the &lt;em&gt;cleanest&lt;/em&gt; in the whole sample — 1.9% thin descriptions, 7.1% without tags, better than products created one at a time. Almost the entire effect sits in the 50-and-over band (38.4% thin, 56.4% with one image or none). So the honest statement is: &lt;strong&gt;very large batches are much thinner; medium ones are not, and are sometimes better than hand-built products.&lt;/strong&gt; Our batch rule is also date-based, so a merchant who spent a careful Tuesday adding 25 products by hand gets counted as a batch.&lt;/p&gt;

&lt;p&gt;Also, two fields that look damning are not: &lt;code&gt;product_type&lt;/code&gt; was blank on 36.6% of all 20,604 products and tags on 19.9% — but those gaps are nearly as large outside the batches as inside. Those are not import damage. That is just a field nobody fills in.&lt;/p&gt;

&lt;h2&gt;
  
  
  How this sits next to Klaviyo, if you already run it
&lt;/h2&gt;

&lt;p&gt;We are asked this often enough to answer it plainly: Klaviyo is not on the other side of a comparison table from us. The two tools read different halves of the same store, which is why "which one should I buy" is usually the wrong question about them.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;What it reads&lt;/th&gt;
&lt;th&gt;What it acts on&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Klaviyo's AI&lt;/td&gt;
&lt;td&gt;Customer and event data: who bought, who browsed, who lapsed&lt;/td&gt;
&lt;td&gt;Messages — the email or SMS that goes out, who gets it, when&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arvio&lt;/td&gt;
&lt;td&gt;Product records: description, type, tags, images, price, variant availability&lt;/td&gt;
&lt;td&gt;The records themselves, each change held for your approval&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The seam between them is the thing worth setting up. A back-in-stock flow is only as good as the availability flag behind it: if a variant flipped and the record never moved, the flow has nothing to fire on. A winback campaign pointed at a product whose description is two sentences is sending traffic to a page that cannot close. &lt;strong&gt;Fix the records, then let the messaging tool do what it is good at.&lt;/strong&gt; Neither one replaces the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you should stay where you are
&lt;/h2&gt;

&lt;p&gt;Most posts on this search term are written by a vendor, and the useful thing a vendor can do is tell you when not to buy from them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If what hurts is that buyers can't reach anyone, install a support agent, not us.&lt;/strong&gt; Concretely: your inbox has unanswered messages older than a day; the same five questions arrive every week about shipping times, sizing and returns; you answer chats yourself between 9pm and 11pm; someone asked pre-purchase whether an item fits, got no reply, and didn't buy. That is a staffing problem with a software answer, and the answer is a tool built for conversations — Tidio and Fin are two of the names on the first page for this search, and their own homepages say plainly which job they do. Arvio will not answer a single one of those messages. It cannot see the message.&lt;/p&gt;

&lt;p&gt;If the agent you are weighing is Shopify's own, we ran the same split on it in &lt;a href="https://arvio.a.xyz/blog/shopify-ai-agent-vs-sidekick?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_blog3" rel="noopener noreferrer"&gt;Shopify AI agent vs Sidekick&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A test that separates them cleanly.&lt;/strong&gt; Count what you lost last month in two buckets: revenue lost because nobody replied, versus revenue lost because a page was wrong, thin or quietly unavailable. Buy for the bigger bucket. For a lot of stores under a thousand orders a month, the bigger bucket is the first one, and it is not close.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two more cases where we are the wrong answer.&lt;/strong&gt; If your catalogue is under about thirty products, you can do the record work yourself in an evening and an agent is overhead — nothing above applies to you at that size. And if what you need is a custom workflow wired across your own internal tools, you want a builder platform — which is a real category, and one of the nine homepages we read is selling exactly that. A packaged store agent, ours included, will be too opinionated about what it touches.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we did not test
&lt;/h2&gt;

&lt;p&gt;We did not install, trial or use any of the nine products. We did not compare quality, resolution rates or pricing, and nothing here says any of these products is better or worse than any other — only which job each one puts on its own front page. We also did not test whether any of them edit catalogue records; the absence of those phrases from a homepage is not evidence of absence in the product. The catalogue figures come from a convenience frame read on one day through one public endpoint, and they describe those 41 stores, not Shopify.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Knowing which aisle you're in doesn't fix the shelf&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the answer was the record side, somebody still has to open each product and type. Arvio sits on that side of the split; the listing is the place to judge whether it fits your store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=ai-agent-for-ecommerce&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_listing_mid" rel="noopener noreferrer"&gt;Install Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is an AI agent for ecommerce?
&lt;/h3&gt;

&lt;p&gt;The phrase currently covers at least two unrelated jobs, and the search results only show one of them. On the nine first-page homepages we could read on 27 September 2026, seven advertise work on customer conversations — chat, tickets, inbox, handoff. Zero advertise work on store records. When someone says "AI agent for ecommerce" without qualifying it, they almost always mean the first one, because that is what the market looks like.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are all ecommerce AI agents just chatbots?
&lt;/h3&gt;

&lt;p&gt;No, and our data can't support that claim — it is about homepage copy, not products. Of nine readable homepages, seven advertise conversation work, one is a platform for building your own agents (zero conversation phrases, six builder ones), and one matched none of our 44 phrases at all. A tenth domain would not load for us and is excluded from those counts entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is your denominator nine and not ten?
&lt;/h3&gt;

&lt;p&gt;Because one of the ten domains did not return a page on the run we used. The browser reported a closed connection, and the plain HTTPS fallback failed at the TLS layer. Counting it as "zero record-work phrases" would have strengthened our headline and would have been false — we did not read that page, so we know nothing about it. We don't name it, because a single load failure on one afternoon says more about that afternoon than about the company. Not readable is its own bucket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does a support agent handle inventory problems?
&lt;/h3&gt;

&lt;p&gt;The ones whose homepages we read describe order lookups, cart recovery and product recommendations inside a conversation. That is different from noticing, with nobody in the chat, that one variant of a live product went to zero three weeks ago. In our 41-store sample that state existed on 15.3% of multi-variant products. We went into why Shopify's own alerting misses it in &lt;a href="https://arvio.a.xyz/blog/shopify-low-stock-alert?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_blog5" rel="noopener noreferrer"&gt;Shopify does not have a low stock alert&lt;/a&gt;. Whether any specific product handles it is a question for that vendor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I check the 15.3% number on my own store?
&lt;/h3&gt;

&lt;p&gt;Not exactly, with a browser alone. The Ctrl-F method near the top counts out-of-stock &lt;em&gt;variants&lt;/em&gt;, which is a prompt to investigate rather than the same measure. The 15.3% counts &lt;em&gt;products&lt;/em&gt; where at least one variant is unavailable and at least one is still available, which requires grouping variants under their parent — a script, not a find bar. The find-bar count will tell you within a minute whether there is anything to investigate at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Arvio answer customers?
&lt;/h3&gt;

&lt;p&gt;No — it sits on the record side of the split this whole post is about, and it cannot see a customer message. If you need customer replies, the section above on staying where you are names the category you actually want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Klaviyo a competitor?
&lt;/h3&gt;

&lt;p&gt;No — the two act on different halves of the store. Klaviyo's AI acts on messages; Arvio acts on the product records those messages point at. The failure mode we see is running good campaigns into pages that are thin or quietly out of stock.&lt;/p&gt;

&lt;h2&gt;
  
  
  One tab, one Ctrl-F
&lt;/h2&gt;

&lt;p&gt;If you read only one thing here: the two aisles are real, they do not overlap, and the first page of results only shows you one of them — nine homepages, eighteen chances each to mention catalogue work, zero mentions.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;/products.json?limit=250&lt;/code&gt; on your own storefront and search it for &lt;code&gt;"available":false&lt;/code&gt;. If you get no hits, your record side is quiet today and a conversation tool is probably the better spend. If you get a screenful, you have just found work that nobody was ever going to file a ticket about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=ai-agent-for-ecommerce&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_listing_end" rel="noopener noreferrer"&gt;see it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; We are on the record side of the split above — the listing is where to check whether that is the side your store is losing money on.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/ai-agent-for-ecommerce?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/ai-agent-for-ecommerce&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=ai-agent-for-ecommerce_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Matrixify Alternatives: What Each One Is Actually For</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Fri, 25 Sep 2026 15:07:37 +0000</pubDate>
      <link>https://dev.to/arvio/matrixify-alternatives-what-each-one-is-actually-for-4d9h</link>
      <guid>https://dev.to/arvio/matrixify-alternatives-what-each-one-is-actually-for-4d9h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/matrixify-alternative?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/matrixify-alternative&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;If you are moving data in or out of Shopify in bulk, Matrixify is a good answer to that question and this article will not talk you out of it.&lt;/strong&gt; It is a well-regarded import/export tool and the sections below say exactly which jobs it suits.&lt;/li&gt;
&lt;li&gt;"Alternative" usually means one of three different requests. Moving data. Editing a field across many products. Deciding what each product should say. They look similar on a spreadsheet and they are not the same job.&lt;/li&gt;
&lt;li&gt;The third one is where files run out. A file can put a value in a column for you; it cannot work out what the value should be for each product, because that answer is different for every row.&lt;/li&gt;
&lt;li&gt;Before you shop for anything, read your own catalogue. On the 41 stores we measured, the median store had &lt;strong&gt;13.3%&lt;/strong&gt; of products with no product type — but the pooled figure across all products is &lt;strong&gt;36.6%&lt;/strong&gt;, and the gap between those two numbers is the whole point of checking your own.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Different job, same catalogue&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvio is an AI store operator: you tell it what you want, it reads your live catalogue, decides what each product needs, and drafts the change for you to approve. It does not move files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=matrixify-alternative&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why you can trust us, and where we are interested
&lt;/h2&gt;

&lt;p&gt;We build Arvio, a Shopify app. It is not an import/export tool and it is not competing with Matrixify for the migration job — we will say so again in the section where it matters. We have no commercial relationship with Matrixify and we are not a reseller of anything mentioned here.&lt;/p&gt;

&lt;p&gt;What that means practically: on the jobs Matrixify is built for, we have no product to sell you, so the description below is just a description. On the third job, we do have something to sell, and that section is labelled.&lt;/p&gt;

&lt;p&gt;Everything quoted about Matrixify in this article was read from its own public pages on 2026-09-25 — the App Store listing, its homepage and its pricing page. We have not run its paid tiers, so nothing here is a performance claim about it. Where we could not verify something, it is left out rather than guessed at.&lt;/p&gt;

&lt;h2&gt;
  
  
  The request splits three ways
&lt;/h2&gt;

&lt;p&gt;People arrive at "Matrixify alternative" from very different places. Sorting yourself into one of these first will save you most of the shopping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Job one: move data.&lt;/strong&gt; Get products out of one system and into another, or out of Shopify and into a spreadsheet, or from a supplier's feed into your catalogue. Migration, backup, store-to-store copying, scheduled feeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Job two: change one field across many products.&lt;/strong&gt; The vendor name is wrong on four hundred products. A collection of items needs a tag added. Prices go up 8% on one supplier's range and back down after a sale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Job three: decide what each product should say.&lt;/strong&gt; Three hundred descriptions are two lines long. Product type is blank on a third of the catalogue and no two products need the same value.&lt;/p&gt;

&lt;p&gt;Job one and job two both end in a file. Job three cannot, and that is not a criticism of files — it is what a file is. A spreadsheet is very good at carrying a decision you have already made to a lot of rows at once. It has no view on what the decision should be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Job one: moving data. This is what Matrixify is for.
&lt;/h2&gt;

&lt;p&gt;This is the section where the honest answer is "you already have the tool."&lt;/p&gt;

&lt;p&gt;Matrixify's own one-line description of itself is "Matrixify app helps you to manage store data - bulk import, export, update and migrate." (read 2026-09-25) Its listing names the capabilities directly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Import and Export data using Excel, Google Sheets or CSV files.&lt;/p&gt;

&lt;p&gt;Migrate from WooCommerce, WordPress, Magento, BigCommerce, Lightspeed, others.&lt;/p&gt;

&lt;p&gt;Backup data, restore data. Copy data from store to store.&lt;/p&gt;

&lt;p&gt;Schedule Export and schedule Import jobs, auto-repeat.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On its own homepage it lists the object types it handles: products, collections, customers, companies, discounts, draft orders, orders, payouts, pages, blog posts, redirects, activity, files, menus, metaobjects, metafields and shop data.&lt;/p&gt;

&lt;p&gt;Two things there are worth pulling out, because they are the reason people reach for it rather than Shopify's built-in CSV.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope.&lt;/strong&gt; Shopify's native product CSV moves products. The list above is considerably longer than that, and if the thing you need to move is redirects or metaobjects, the built-in export does not have a column for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File size.&lt;/strong&gt; Shopify's own documentation states the native limit plainly: "Your product CSV can't exceed 15 MB." Matrixify's listing says it handles "files up to 20 GB" (read 2026-09-25). We have not tested that ceiling and are not vouching for it; we are noting that the constraint people hit with the native importer is a real constraint, and that this is the category of tool that addresses it.&lt;/p&gt;

&lt;p&gt;There is a third one that matters more than it sounds. Shopify's CSV importer has a behaviour that catches people: "If a non-required column in the import CSV file is blank, then the matching value in the product list is overwritten as blank." A column that exists in your file but is empty will wipe the live value. And with the overwrite box unchecked, "the products that match an existing handle are ignored during CSV import" — so the safe-looking option is the one that silently does nothing. We wrote about &lt;a href="https://arvio.a.xyz/blog/shopify-fix-catalog-after-import?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_blog2" rel="noopener noreferrer"&gt;what that does to a catalogue after an import goes wrong&lt;/a&gt; separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When you should stay on Matrixify, or go to something like it:&lt;/strong&gt; you are migrating a store, you are backing one up, you are copying between stores, you are pulling a supplier feed on a schedule, or you need to move an object type that Shopify's native export does not cover. Those are the jobs it names on its own listing, and nothing in this article is an argument against using it for them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it is worth looking elsewhere for job one:&lt;/strong&gt; if you are doing a one-time migration off a single platform, dedicated migration apps exist for exactly that shape and may be cheaper for a job you do once. We have not benchmarked them and are not naming a winner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Job two: editing a field in bulk
&lt;/h2&gt;

&lt;p&gt;This is the fuzzy middle, and it is where most of the "alternative" searching happens.&lt;/p&gt;

&lt;p&gt;You can do job two with an import/export tool: export, edit the column in a spreadsheet, import it back. Matrixify's homepage describes this update path directly, saying the app lets you "update only fields you want to update, without the need to re-import everything" (read 2026-09-25). That is a real distinction from a full re-import and it is why the round trip works.&lt;/p&gt;

&lt;p&gt;You can also do it with Shopify's own bulk editor, which handles a set of fields in a grid in the admin without any file at all. For a few hundred products and a field the bulk editor exposes, that is often faster than a round trip.&lt;/p&gt;

&lt;p&gt;And there is a whole category of dedicated bulk edit apps built around this job specifically, usually with things a file round trip does not give you — filtered selections, scheduled changes, a preview of what will change, and a way back.&lt;/p&gt;

&lt;p&gt;The honest guidance here is not a product name. It is one question: &lt;strong&gt;is the round trip the annoying part, or is the deciding part the annoying part?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you know exactly what the new values are and the only tedium is getting them in, any of the three approaches work and you should pick on price and how often you will do it. If you are staring at the export wondering what to type in the column, no tool in this paragraph helps, because all of them are waiting for you to type it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You have just seen where the spreadsheet stops&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The column is easy to fill once you know what goes in it. Deciding what goes in it, product by product, against your own data, is the part a file cannot do for you. That is the part Arvio drafts, and every draft waits for your approval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=matrixify-alternative&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_listing_mid" rel="noopener noreferrer"&gt;Install Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Job three: deciding what each product should say
&lt;/h2&gt;

&lt;p&gt;This is the one we build for, so read this section knowing that.&lt;/p&gt;

&lt;p&gt;The distinction is narrower than it sounds, and it is easiest to see on a single field. Take product type, a field that is blank on a lot of catalogues.&lt;/p&gt;

&lt;p&gt;Filling it for one product is a decision — you look at the thing and you know what it is. Filling it for four hundred products is four hundred decisions, and they are not the same decision repeated. You cannot write one rule that covers a catalogue that has both a ceramic mug and a gift card in it. So the export comes back with four hundred blank cells, and the file has done everything it can do. The remaining work is the work.&lt;/p&gt;

&lt;p&gt;That is the boundary. &lt;strong&gt;Matrixify moves the data in and out. Arvio decides what the data should say and drafts it for you.&lt;/strong&gt; Neither one does the other's job, and an article that pretended otherwise would be easy to catch out.&lt;/p&gt;

&lt;p&gt;Concretely, what that looks like: Arvio reads your live catalogue, works out what each product needs from the fields that are actually there — vendor, options, the copy you already wrote — drafts the change, and shows it to you before anything is written. You approve or you do not. We have written elsewhere about &lt;a href="https://arvio.a.xyz/blog/arvio-what-it-wont-touch?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_blog4" rel="noopener noreferrer"&gt;what it will not touch&lt;/a&gt; and what &lt;a href="https://arvio.a.xyz/blog/product-description-examples-shopify?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_blog5" rel="noopener noreferrer"&gt;a description that does the work&lt;/a&gt; looks like when it is written against real product data rather than a template.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When you should not use us for this:&lt;/strong&gt; if you already know what every product needs and it is the same value for all of them, the deciding part is dead weight and you want a bulk edit tool or a file. That is a real case and it is common.&lt;/p&gt;

&lt;h2&gt;
  
  
  A side-by-side, with the honest ticks
&lt;/h2&gt;

&lt;p&gt;This table is about which jobs each shape of tool is built for, not which product is better. We have marked Matrixify from what its own public pages state.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Matrixify&lt;/th&gt;
&lt;th&gt;Shopify native CSV / bulk editor&lt;/th&gt;
&lt;th&gt;Arvio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bulk import products from a file&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓ (products, 15 MB cap)&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Export the full catalogue to Excel / Sheets&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓ (CSV)&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Migrate from another platform&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backup and restore&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy data store to store&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scheduled / auto-repeating jobs&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object types beyond products&lt;/td&gt;
&lt;td&gt;✓ (long list, see above)&lt;/td&gt;
&lt;td&gt;partial&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update individual fields without a full re-import&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓ (bulk editor, limited fields)&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works out what the value should be per product&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drafts the change and waits for approval&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The bottom two rows are not marks against Matrixify. They are outside what it says it does, in the same way that "migrate from Magento" is outside what we do. A tool is not worse for having a scope.&lt;/p&gt;

&lt;p&gt;We have deliberately not put pricing in this table. Plans and limits change, and a stale price in a comparison table is worse than no price — go and read each vendor's current pricing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read your own catalogue before you shop
&lt;/h2&gt;

&lt;p&gt;Whichever job you are in, the size of it is knowable before you spend anything, and it is the one number that should drive the decision.&lt;/p&gt;

&lt;p&gt;In August 2026 we read 41 live Shopify storefronts — 20,604 products — through the public &lt;code&gt;/products.json&lt;/code&gt; endpoint that any browser can fetch. The stores came from a public list: the Shopify Community's Store Feedback board, where owners post their own URLs asking for reviews. No store is named here.&lt;/p&gt;

&lt;p&gt;Here is the part that matters for your decision, and it is why we are giving you two numbers for every row rather than one:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What we measured&lt;/th&gt;
&lt;th&gt;Across all products&lt;/th&gt;
&lt;th&gt;Median store&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Product type blank&lt;/td&gt;
&lt;td&gt;36.6%&lt;/td&gt;
&lt;td&gt;13.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tags blank&lt;/td&gt;
&lt;td&gt;19.9%&lt;/td&gt;
&lt;td&gt;7.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Description under 200 characters&lt;/td&gt;
&lt;td&gt;21.4%&lt;/td&gt;
&lt;td&gt;1.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One image or none&lt;/td&gt;
&lt;td&gt;34.6%&lt;/td&gt;
&lt;td&gt;14.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Title over 60 characters&lt;/td&gt;
&lt;td&gt;13.6%&lt;/td&gt;
&lt;td&gt;2.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the left column on its own and you would conclude every store has a description problem. Read the right column and most do not — the typical store has &lt;strong&gt;1.4%&lt;/strong&gt; thin descriptions, while the pooled figure is &lt;strong&gt;21.4%&lt;/strong&gt;, because a small number of large catalogues carry most of the affected products. Both numbers are true. Only one of them is about you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whether it looks like you.&lt;/strong&gt; Stores that ask for feedback on a public board skew newer and smaller, and the stores were drawn from that board's list with a fixed random seed, so this is a random sample of that list and not of Shopify at large. The median store here is smaller than the average catalogue we get asked about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to check yours in five minutes, without installing anything.&lt;/strong&gt; Open &lt;code&gt;https://yourstore.com/products.json?limit=250&lt;/code&gt; in a browser. You will get one very long line of JSON — that is normal and it is the wall most people hit. Rather than reading it, use your browser's find (⌘F or Ctrl-F) and count matches for &lt;code&gt;"product_type":""&lt;/code&gt; and for &lt;code&gt;"tags":[]&lt;/code&gt;. Those two counts, against the number of products actually in that response, give you your own version of the table above. One request returns at most 250 products, so if your catalogue is larger, add &lt;code&gt;&amp;amp;page=2&lt;/code&gt;, &lt;code&gt;&amp;amp;page=3&lt;/code&gt; and so on and add the counts up — otherwise you are measuring your first 250 products and calling it your catalogue. If your numbers look like the median column, the job is an afternoon and you do not need to buy anything. If they look like the pooled column, you have a real project and it is worth picking the right shape of tool for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three real situations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;"We're moving off WooCommerce next month."&lt;/strong&gt; Job one. An import/export tool or a dedicated migration app. Nothing in job three is relevant until the products are actually in Shopify, and buying for it now is buying early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"The supplier changed their naming and now 300 vendor fields are wrong."&lt;/strong&gt; Job two, and the cleanest case for a round trip: you know the old value, you know the new value, and a find-and-replace in a column does it. Export, edit, import back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Product type is blank on a third of the catalogue."&lt;/strong&gt; Job three. The export will tell you which ones, which you could also learn with the ⌘F count above. It will not tell you what to put in them, and neither will an empty column.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Matrixify good?&lt;/strong&gt;&lt;br&gt;
For the jobs it describes on its own listing — bulk import, export, migration, backup, scheduled jobs — it is a well-established app in that category with a long-standing presence on the App Store. We have not run its paid tiers, so we are not rating it on performance. If your job is moving data, it belongs on your shortlist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need an alternative to Matrixify at all?&lt;/strong&gt;&lt;br&gt;
Often not. If you are here because an import felt harder than it should have, the problem is sometimes the file rather than the tool — particularly the blank-column behaviour described above. If you are here because the tool did its job and you still have work left, you are probably in job three, and that is not a like-for-like replacement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can Arvio import my products from a CSV?&lt;/strong&gt;&lt;br&gt;
No. It is not an import/export tool. If you need data moved into Shopify in bulk, use something built for that — Matrixify among them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the cheapest way to do a one-off bulk edit?&lt;/strong&gt;&lt;br&gt;
Shopify's own bulk editor, if the field you need is one it exposes, costs nothing extra. For fields it does not expose, an export-edit-import round trip on an entry tier of an import tool is usually the next cheapest. Check current plan limits with the vendor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does the pooled percentage differ so much from the median store?&lt;/strong&gt;&lt;br&gt;
Because catalogue sizes vary enormously. A single store with thousands of thin descriptions moves the pooled number a long way and leaves the median untouched. Any comparison article quoting only a pooled figure is telling you about the biggest store in its sample, not about yours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is &lt;code&gt;/products.json&lt;/code&gt; safe to open on my own store?&lt;/strong&gt;&lt;br&gt;
It is a read-only public endpoint that any browser can fetch, and opening it changes nothing. It shows published products only, so the counts you get are for your live catalogue rather than drafts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use Matrixify and Arvio together?&lt;/strong&gt;&lt;br&gt;
Yes, and that is the arrangement we would expect for a store doing both jobs — one moves the data, the other decides what it should say. They do not overlap.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we still do not know
&lt;/h2&gt;

&lt;p&gt;We have not run Matrixify's paid tiers against a large catalogue, so nothing here is a performance or reliability claim about it; the descriptions come from its own public pages, read on 2026-09-25. We have not benchmarked the dedicated bulk edit apps or migration apps mentioned by category, which is why none of them are named or ranked. And the 41-store figures above come from a seeded random draw on one public board — they are useful for showing how far pooled and per-store numbers diverge, and they are not a Shopify-wide benchmark.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=matrixify-alternative&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; Keep Matrixify for moving the data; this is for deciding what the data should say.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/matrixify-alternative?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/matrixify-alternative&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=matrixify-alternative_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Shopify inventory not syncing: which layer is actually wrong</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Fri, 25 Sep 2026 15:06:44 +0000</pubDate>
      <link>https://dev.to/arvio/shopify-inventory-not-syncing-which-layer-is-actually-wrong-3dc4</link>
      <guid>https://dev.to/arvio/shopify-inventory-not-syncing-which-layer-is-actually-wrong-3dc4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/shopify-inventory-not-syncing?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/shopify-inventory-not-syncing&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Published September 25, 2026 by &lt;a href="https://apps.shopify.com/partners/adot-inc?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_listing1" rel="noopener noreferrer"&gt;Adot Technologies Inc&lt;/a&gt;, the team behind &lt;a href="https://apps.shopify.com/arvio?article_slug=shopify-inventory-not-syncing&amp;amp;source_section=byline&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_listing2" rel="noopener noreferrer"&gt;Arvio: AI Store Operator&lt;/a&gt;. Every sentence quoted from Shopify's documentation below was read on September 25, 2026 and is reproduced word for word; quotation marks are also used for the things merchants say, which are ours, not Shopify's. Where Shopify does not document something, this article says so instead of guessing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Someone counted the shelf. The admin disagrees. Or the admin looks right and the product page says sold out anyway.&lt;/p&gt;

&lt;p&gt;The word people reach for is "syncing", and it points at the wrong thing most of the time. A sync failure means a number left one system and did not arrive in the other. That happens, and there is a section on it below. But in most stores the number arrived fine — it is just not the number you were looking at, because Shopify keeps several and shows you different ones in different places.&lt;/p&gt;

&lt;p&gt;So the first job is not fixing anything. It is working out which of the six things below you have. Four of them are settings you can rule out in about a minute each; the fifth takes a test import to confirm, and the sixth is not something you fix in the admin at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Check On hand against Available before anything else.&lt;/strong&gt; They are different numbers on purpose. Shopify: &lt;em&gt;"On hand inventory is made up of the total of your Committed, Unavailable, and Available inventory."&lt;/em&gt; An order that came in and has not shipped yet moves units into Committed, so Available drops while the shelf has not changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If your storefront says sold out and the admin says you have stock, look at locations before you look at your theme.&lt;/strong&gt; Inventory at a location that does not fulfil online orders is &lt;em&gt;"still counted in your total inventory, but not in your online quantity"&lt;/em&gt; — and the online quantity is the one shoppers see.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A dash instead of a number means the product is not active at that location&lt;/strong&gt;, which is not the same as having zero there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A CSV import can blank a field you did not mean to touch.&lt;/strong&gt; Shopify: &lt;em&gt;"If a non-required column in the import CSV file is blank, then the matching value in the product list is overwritten as blank."&lt;/em&gt; Note the trap in that sentence: a column that is present but empty is destructive, while a column left out entirely is safe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where Shopify does not document something, this article says so rather than guessing.&lt;/strong&gt; Three of the checks below end with "go and look in your own admin" for exactly that reason: the official pages do not settle them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There is exactly one cause here that loses units silently&lt;/strong&gt;, and it is two systems writing the same inventory level without concurrency control. Shopify's own worked example ends: &lt;em&gt;"Result: The final available inventory value is 90, but it should be 70 (20 units lost)."&lt;/em&gt; No error is raised anywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Your storefront number is right; your mental model of it is what is off&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most of the causes below are settings you can check yourself in about a minute. Working through a catalogue afterwards is the slow part: Arvio reads your products one at a time, drafts changes, and applies nothing you have not approved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=shopify-inventory-not-syncing&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_listing_top" rel="noopener noreferrer"&gt;Install Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The quick version
&lt;/h2&gt;

&lt;p&gt;Open one product in your admin, on the variant that is wrong, and answer three questions in this order. Each one eliminates a whole family of causes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Does On hand match the shelf?&lt;/strong&gt; If yes, nothing was lost — skip to the Available question. If no, you have either an untracked item, a CSV that overwrote it, or a genuine write conflict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does Available match On hand?&lt;/strong&gt; If Available is lower, look at Committed and Unavailable on the same card. That gap is orders you have not shipped, or stock an app has set aside.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is the number you are comparing the online quantity?&lt;/strong&gt; The inventory card lists every location. If some of that stock sits at a location that does not fulfil online orders, the storefront never counted it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In our experience most "not syncing" reports die at question 2 or 3 — we have no figure for that, it is a pattern from reading them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cause 1: Available and On hand were never the same number
&lt;/h2&gt;

&lt;p&gt;This is the most common one, and it is not a fault. Shopify holds inventory in states, and the definitions are worth reading once because they explain nearly every discrepancy people report:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"On hand inventory refers to all inventory units that you have at a location. On hand inventory is made up of the total of your Committed, Unavailable, and Available inventory."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Available inventory refers to inventory that you can sell. Available inventory isn't committed or set aside as Unavailable."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Committed inventory refers to the number of units that are set aside and can't be sold, such as units in an unfulfilled order, reserved in a draft order, or in a transfer that's marked as ready to ship."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Unavailable inventory refers to the number of units set aside by apps or held for other reasons, such as damaged, quality control, or safety stock."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So: an order lands, nobody has packed it yet, and Available drops even though the box is still in the back room. On hand has not moved. The shop floor and the admin are both telling the truth about different things.&lt;/p&gt;

&lt;p&gt;The one to look at hardest is &lt;strong&gt;Unavailable&lt;/strong&gt;, because its definition contains the phrase &lt;em&gt;"set aside by apps"&lt;/em&gt;. If you have a number sitting in Unavailable that you did not put there, an app did, and that is your answer — it is not a sync problem, it is another piece of software doing its job where you could not see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cause 2: the stock is real, but it is at a location the storefront does not count
&lt;/h2&gt;

&lt;p&gt;If the admin shows stock and the product page says sold out, this is where to look next.&lt;/p&gt;

&lt;p&gt;Shopify keeps a separate figure called the online quantity:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If you have locations that don't fulfill online orders, such as retail-only stores, then their inventory is still counted in your total inventory, but not in your online quantity. The online quantity is what displays to customers in your online store and determines whether a product displays as available."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it is explicit about what happens when you split stock across a fulfilling and a non-fulfilling location:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If you have an item at a location that fulfills online orders with an inventory level of zero or below, and a location with available inventory that doesn't fulfill online orders, then that item is still displayed as out of stock to customers on your online store."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The switch that causes this has a specific name, which is worth knowing because searching for the wrong name wastes an afternoon. In &lt;strong&gt;Settings → Locations&lt;/strong&gt;, on the location itself, in the Fulfillment section, it is the &lt;strong&gt;Use inventory at this location to fulfill online orders&lt;/strong&gt; toggle. Turning it off does what you would expect, and Shopify spells out the consequence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Preventing a location from fulfilling online orders removes any inventory assigned to the location from a product's online quantity."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One thing that catches people who run a shop as well as a site: that stock has not been quarantined entirely. Shopify notes that &lt;em&gt;"The location's inventory can still be used to fulfill draft orders and orders from other sales channels."&lt;/em&gt; So the same units can look invisible on your product page and perfectly usable when you build a draft order, which reads exactly like a sync bug and is not one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cause 3: a dash where you expected a number
&lt;/h2&gt;

&lt;p&gt;This one is quick and it confuses almost everyone the first time.&lt;/p&gt;

&lt;p&gt;On the inventory card, a product can be recorded at a location and still show a dash instead of an Available figure. Shopify:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If On hand is recorded at a location but Available is a dash, then the variant is inactive at that location."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inactive is not zero. The units are counted in your totals and cannot be sold from there. The same thing bites when you open a new location, because stocking it is two separate actions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"When you add a new store location, your existing products aren't automatically stocked or activated at that location."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"If you record inventory at the new location but the product isn't active, then the Available quantity displays a dash."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you can load a new warehouse with stock, watch the numbers go in correctly, and still sell nothing from it. Nothing failed to sync. The product was never switched on there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cause 4: tracking is off, or the tracking lives somewhere else
&lt;/h2&gt;

&lt;p&gt;Shopify's rule for what "out of stock" even means starts with tracking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"An item is out of stock when inventory is tracked and the inventory level is at zero or below."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read that carefully, because the condition is doing real work. If tracking is not on for an item, an inventory level is not what decides whether it can be sold. Shopify also states the prerequisite plainly: &lt;em&gt;"Before you can view or adjust inventory levels for a product, you need to set up inventory tracking for that product."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There is a related setting that produces the opposite complaint — "it let someone buy something we do not have". That is &lt;strong&gt;Continue selling when out of stock&lt;/strong&gt;, and Shopify notes a dependency and an exception:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"You can select the Continue selling when out of stock option only when you turn on the Inventory tracked setting."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Continue selling when out of stock doesn't apply to orders placed from Shopify POS."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And if an app manages the inventory, the picture changes again:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If a product's inventory quantity is tracked using inventory apps, then its quantities are allocated only to that app location."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;One thing to check in your own admin rather than take from us.&lt;/strong&gt; People often ask whether tracking is set per variant or per product, since a store will have one variant behaving differently from its siblings. Shopify's out-of-stock page describes selecting the setting &lt;em&gt;"from the Inventory section of a product or variant in your Shopify admin"&lt;/em&gt;, which is the wording we are willing to stand behind. We could not find an official sentence stating the scoping rule outright, so open the specific variant that is misbehaving and look at its own Inventory section rather than assuming it inherited whatever the product-level setting says.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cause 5: a CSV import overwrote it
&lt;/h2&gt;

&lt;p&gt;If the number was right on Monday and wrong on Tuesday, and somebody uploaded a spreadsheet in between, start here.&lt;/p&gt;

&lt;p&gt;Shopify's rules for the overwrite option are precise, and the two halves both matter:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If you select this option, then when the handle in the import CSV file matches an existing handle in your products list, the values in the CSV file overwrite the values in the matching columns in the existing product list."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"If the overwrite option isn't selected, then the products that match an existing handle are ignored during CSV import."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then comes the rule that does the real damage, and it is the opposite of what most people assume:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If a non-required column in the import CSV file is blank, then the matching value in the product list is overwritten as blank."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"If a non-required column isn't included in the import CSV file, but is included in the existing product list, then the value in the product list remains the same."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A column you deleted from the file is safe. A column you left in the file but emptied will wipe what is in the store. That is exactly backwards from the intuition of "if I clear it out, nothing will happen", and it is why a file that has been round-tripped through a spreadsheet can quietly flatten fields nobody edited.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check this one in your own admin before acting on it.&lt;/strong&gt; Shopify states those rules for non-required columns generally; the page does not name the inventory quantity column specifically. So do not take our word for how your inventory column behaves — export one product, run the import you are worried about against that single product, and look at what moved. We wrote up the wider version of this problem, including what to repair after an import has already run, in &lt;a href="https://arvio.a.xyz/blog/shopify-fix-catalog-after-import?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_blog4" rel="noopener noreferrer"&gt;fixing your Shopify catalog after a bad CSV import&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Finding the setting takes a minute. The catalogue behind it does not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvio: AI Store Operator goes through your products one at a time. What it changes, what it leaves alone and what it got wrong on a real store, we wrote up separately in &lt;a href="https://arvio.a.xyz/blog/what-arvio-actually-does?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_blog5" rel="noopener noreferrer"&gt;what Arvio actually does&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=shopify-inventory-not-syncing&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_listing_mid" rel="noopener noreferrer"&gt;Install Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cause 6: two systems writing the same number, and this one really does lose units
&lt;/h2&gt;

&lt;p&gt;Everything above is a number being read wrong. This one is a number being destroyed, and it is the only cause here that deserves the word "syncing".&lt;/p&gt;

&lt;p&gt;When an app writes inventory levels — a 3PL, a POS integration, an ERP connector, a warehouse tool — Shopify offers a concurrency mechanism, and offering it implies the obvious: two things can write the same level at once.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The changeFromQuantity field enables concurrency control by allowing you to specify the quantity that you expect to be present before your change is applied. If the current quantity doesn't match the value that you provide, then the mutation fails with a CHANGE_FROM_QUANTITY_STALE error, preventing unintended overwrites."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Shopify's own worked example of what happens without it is unusually clear. An app reads 100 units, decides to take 10 off, and while it is thinking, 20 units sell elsewhere:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Result: The final available inventory value is 90, but it should be 70 (20 units lost)."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nothing errors. No log says anything. The number is simply wrong afterwards, and it stays wrong until someone counts the shelf — which is normally how this gets discovered, weeks later, as "our inventory keeps drifting".&lt;/p&gt;

&lt;p&gt;There is also a documented reason an app might skip the safeguard on purpose:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"If you don't care about the current quantity because you're the source of truth, then you don't need to implement compare and swap and should opt out."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a legitimate design choice, and it is also the thing to ask your vendor about. If two of your systems both believe they are the source of truth, they will take turns overwriting each other and both of them will be behaving as designed. This is not a setting you can fix in the admin; it is a question of which system is allowed to decide, and the answer has to be one of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we could not confirm.&lt;/strong&gt; We looked for official documentation of how long inventory writes take to appear, and did not find any. Shopify does not publish a sync lag figure, so if someone tells you to "wait fifteen minutes and it will catch up", that number did not come from Shopify. Likewise, we found no official page describing a storefront caching delay for inventory display. That does not prove neither exists — it means we are not going to assert either.&lt;/p&gt;

&lt;h2&gt;
  
  
  The POS case
&lt;/h2&gt;

&lt;p&gt;If your discrepancy involves a till, there is one documented behaviour worth knowing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Shopify POS needs an internet connection to sync with your Shopify admin, send receipts by email, and capture card payments."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sales made while the connection is down are not reaching your inventory until it returns. That accounts for a specific shape of problem — everything reconciles except the hours you were offline.&lt;/p&gt;

&lt;p&gt;What Shopify does not document, as far as we could find, is what happens when the same unit sells online and in-store during that window. So we are not going to tell you which write wins. If that is your situation, the reconciliation is a manual count, not a setting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article does not know
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We have no access to your admin, and no admin access to any store.&lt;/strong&gt; Every mechanic above comes from Shopify's public documentation, quoted word for word. Where the documentation is silent — variant-level tracking scope, the inventory column's behaviour under CSV overwrite, sync timing, POS conflict resolution — we have said so rather than filled the gap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We did not reproduce these failures in a test store.&lt;/strong&gt; This is a reading of the documentation plus the setting names you will find in the admin, not a lab result. The three "check it in your own admin" notes above are the places where that distinction matters most.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation changes.&lt;/strong&gt; Every Shopify documentation page cited here was read on September 25, 2026; the catalogue figures are a separate August 2026 read, dated where they appear.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The adjacent problem: stock that is genuinely gone and still on the shelf
&lt;/h2&gt;

&lt;p&gt;Fixing the number is one job. What the storefront does with a zero afterwards is another, and it is the one that costs money quietly.&lt;/p&gt;

&lt;p&gt;In August 2026 we read the public catalogue of 41 live Shopify storefronts — 20,604 products, nothing truncated, all from endpoints any browser can fetch, drawn with a fixed random seed from a public list of 230 stores whose owners had posted their own URLs on the Shopify Community's Store Feedback board — 60 were drawn, 41 of which had a readable public catalogue. The draw is random within that list, but the list itself is not a cross-section of Shopify: stores that ask strangers for feedback skew newer and smaller, so read these as a reason to check your own numbers, not as a figure for Shopify at large. Products that were sold out and still listed as live came to &lt;strong&gt;10.3% pooled across all products&lt;/strong&gt;, but the &lt;strong&gt;median store's own rate was 4.6%&lt;/strong&gt; — 2,130 products, present on 31 of the 41 stores.&lt;/p&gt;

&lt;p&gt;Those two figures are far apart, and the gap is the interesting part: pooled, it looks like an industry-wide condition; per store, the typical store has a much smaller version of it and a few large catalogues carry most of the volume. Read the 4.6% as the one that describes a store like yours, and check your own rather than adopting either.&lt;/p&gt;

&lt;p&gt;To be clear about what that measurement is and is not: it counts products that are sold out and still live. It is &lt;strong&gt;not&lt;/strong&gt; a measurement of inventory sync failures, and none of those stores told us why a product was in that state — plenty of merchants leave sold-out products up deliberately, to keep a URL that already ranks and to keep collecting demand signal. We include it because it is the thing people find immediately after they fix their numbers, not as evidence for any cause above.&lt;/p&gt;

&lt;p&gt;If that is the problem you actually have, we covered both halves separately: which of the two sold-out problems you are looking at in &lt;a href="https://arvio.a.xyz/blog/shopify-sold-out-products-still-showing?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_blog7" rel="noopener noreferrer"&gt;sold out products still showing on Shopify&lt;/a&gt;, and whether to take the product page down at all — a decision with SEO consequences in both directions — in &lt;a href="https://arvio.a.xyz/blog/shopify-unpublish-out-of-stock-products?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_blog8" rel="noopener noreferrer"&gt;unpublishing out-of-stock products&lt;/a&gt;. The wider version, auditing a catalogue's inventory data rather than chasing one variant, is in &lt;a href="https://arvio.a.xyz/blog/shopify-inventory-management-audit?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_blog9" rel="noopener noreferrer"&gt;a Shopify inventory management audit&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why does my Shopify inventory show a different number than my supplier's system?&lt;/strong&gt;&lt;br&gt;
Compare On hand rather than Available first. Available excludes Committed units, which Shopify defines as &lt;em&gt;"units in an unfulfilled order, reserved in a draft order, or in a transfer that's marked as ready to ship"&lt;/em&gt; — so an outside system counting physical stock will legitimately disagree with Available while matching On hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does my product show as out of stock when I have inventory?&lt;/strong&gt;&lt;br&gt;
Most often the stock is at a location that does not fulfil online orders, which Shopify says is &lt;em&gt;"still counted in your total inventory, but not in your online quantity"&lt;/em&gt;. Check the inventory card for that variant and see which locations hold the units.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does a dash mean instead of an inventory number?&lt;/strong&gt;&lt;br&gt;
The variant is inactive at that location. Shopify: &lt;em&gt;"If On hand is recorded at a location but Available is a dash, then the variant is inactive at that location."&lt;/em&gt; The stock exists and cannot be sold from there until the product is activated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long should Shopify inventory take to update?&lt;/strong&gt;&lt;br&gt;
We could not find an official figure, so we are not going to give you one. If a number has not moved and you have ruled out the settings above, treat it as a write that did not happen rather than a write that is still on its way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can a CSV import wipe my inventory?&lt;/strong&gt;&lt;br&gt;
An import can overwrite fields, and Shopify is explicit that a column present but blank overwrites the existing value as blank while a column left out entirely leaves it alone. Shopify's overwrite rules do not name the inventory quantity column specifically, so test against a single product before running a large file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did my inventory drift without anyone touching it?&lt;/strong&gt;&lt;br&gt;
If two systems write the same inventory level, one can overwrite the other's change with no error. Shopify documents a &lt;code&gt;changeFromQuantity&lt;/code&gt; check that fails with &lt;code&gt;CHANGE_FROM_QUANTITY_STALE&lt;/code&gt; rather than overwriting — ask whichever app manages your inventory whether it uses it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does turning off a location's online fulfilment hide the stock completely?&lt;/strong&gt;&lt;br&gt;
Not entirely. Shopify notes that &lt;em&gt;"The location's inventory can still be used to fulfill draft orders and orders from other sales channels."&lt;/em&gt; It disappears from the online quantity, not from the store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does "Continue selling when out of stock" work at the till?&lt;/strong&gt;&lt;br&gt;
No. Shopify: &lt;em&gt;"Continue selling when out of stock doesn't apply to orders placed from Shopify POS."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=shopify-inventory-not-syncing&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; It does not fix inventory sync — that work is in the settings above. What it does is the catalogue behind them: reading your products one at a time, drafting the changes, and applying nothing you have not approved.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/shopify-inventory-not-syncing?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/shopify-inventory-not-syncing&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-inventory-not-syncing_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Shopify CSV import errors: the ones that fail loudly, and the one that doesn't</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Fri, 25 Sep 2026 15:06:36 +0000</pubDate>
      <link>https://dev.to/arvio/shopify-csv-import-errors-the-ones-that-fail-loudly-and-the-one-that-doesnt-4m3f</link>
      <guid>https://dev.to/arvio/shopify-csv-import-errors-the-ones-that-fail-loudly-and-the-one-that-doesnt-4m3f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/shopify-csv-import-errors?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/shopify-csv-import-errors&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are two kinds of Shopify CSV import error, and confusing them is what costs people an evening.&lt;/p&gt;

&lt;p&gt;The first kind stops the upload. Shopify refuses the file, or refuses a row, and puts something on screen. Those are annoying, but they are honest: nothing changed, you have a message to search for, and the fix is mechanical.&lt;/p&gt;

&lt;p&gt;The second kind finishes. The banner says the import is done, the product count goes up or stays the same, and your catalogue is now different in a way nobody told you about. This is the kind with no error message to search for — by the time you notice, the thing you're hunting is the difference between what the products used to say and what they say now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The destructive rule is about blank cells, not missing columns.&lt;/strong&gt; Shopify's documentation states that "if a non-required column in the import CSV file is blank, then the matching value in the product list is overwritten as blank" (read 2026-09-25). A column you leave &lt;em&gt;out&lt;/em&gt; of the file is a different case entirely: "if a non-required column isn't included in the import CSV file, but is included in the existing product list, then the value in the product list remains the same." Present-and-empty wipes. Absent leaves alone. There is a third documented case that is easy to miss: a column that "relies on other column data not included in the file" causes existing data to be "deleted or removed" — Shopify's example is keeping SKU while dropping the Option1 columns, which deletes the variant option. Almost every silent import disaster is one of these three, and a spreadsheet makes them look identical.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The overwrite checkbox works the opposite way from how it's usually described.&lt;/strong&gt; When the overwrite option is &lt;em&gt;not&lt;/em&gt; selected, Shopify's documentation says "the products that match an existing handle are ignored during CSV import" (read 2026-09-25). You do not get a second copy of the product. You get an import that reports success and changes nothing — which is its own kind of error, because you then go looking for a bug in your spreadsheet that isn't there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fields a wipe would hit hardest are the ones nobody looks at afterwards — and they are already commonly empty.&lt;/strong&gt; Across 41 live Shopify storefronts we read publicly, product type was blank on 36.6% of products pooled, with a per-store median of 13.3%; tags were blank on 19.9% pooled, median 7.7%. That gap between pooled and per-store is the point: this is not every store's problem evenly, it's a few catalogues carrying most of it. Nobody opens a product page to check whether its product type is still there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The prevention is a pre-upload pass, not a post-import cleanup.&lt;/strong&gt; Export the products you intend to change, delete every column you are not deliberately editing, and check that no cell you meant to leave alone came out of the spreadsheet empty. That takes about five minutes and removes the entire silent category.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An old template is probably not your problem.&lt;/strong&gt; The header row of an export we have on file reads &lt;code&gt;Handle,Title,Body (HTML),Vendor,...&lt;/code&gt;. Column naming has changed presentation over the years, but a saved spreadsheet with the older column names is not in itself the reason a column failed to apply.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Catalogue figures: 41 live Shopify storefronts, 20,604 products, read 2026-08-26 from the public &lt;code&gt;products.json&lt;/code&gt; endpoint, computed 2026-09-21. The stores came at random from a public list of owners who posted their own URL on the Shopify Community's Store Feedback board asking for critique, so read every share here as a reason to check your own store rather than as a figure for Shopify at large. Method at the end.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The import said it succeeded. That is not the same as it being right&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvio reads what actually landed in your catalogue after an import, tells you which fields came in empty or wrong, and drafts each fix against your real product data. Nothing applies until you approve it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=shopify-csv-import-errors&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The loud errors, and why they're the easy half
&lt;/h2&gt;

&lt;p&gt;An import that refuses to run is telling you something true about the file. The categories are narrow, and you can usually tell which one you're in from where it stopped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The file is rejected before anything is read.&lt;/strong&gt; Size is a documented hard stop: Shopify states that "your product CSV can't exceed 15 MB. If you get an error after trying to upload a new CSV file, or if the upload times out, split the CSV file it into multiple smaller files, and then upload each file" (read 2026-09-25). If you exported a large catalogue and edited 200 products in it, splitting is not a workaround — it's the documented answer, and it happens to also reduce the blast radius of everything in the next section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A row is rejected but the rest go through.&lt;/strong&gt; This is the case where a partial import leaves you in an ambiguous state: some products updated, some didn't, and the count on the confirmation doesn't tell you which. Re-running the same file after a fix is safe in the sense that matching is by handle, but it is not safe in the sense of the blank-column rule below — if your file has a column that's blank on rows that already imported fine, the second run wipes those values too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encoding and quoting.&lt;/strong&gt; A file that opens correctly in your spreadsheet can still be malformed as CSV, usually because a description contains a quotation mark or a comma and the escaping didn't survive a round trip through a spreadsheet application. The fix is to save as CSV UTF-8 explicitly rather than whatever the default export gave you.&lt;/p&gt;

&lt;p&gt;We haven't reproduced Shopify's exact error strings against our own store, and we're not going to print strings we haven't confirmed — if you have a message on screen, search that message verbatim, because the wording is the most specific thing you have.&lt;/p&gt;

&lt;p&gt;The useful property of all of these: &lt;strong&gt;nothing has silently changed.&lt;/strong&gt; You still have the catalogue you started the day with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The quiet error: present but empty
&lt;/h2&gt;

&lt;p&gt;Here is the rule, in Shopify's own words.&lt;/p&gt;

&lt;p&gt;Blank cell in a column that is present in the file:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If a non-required column in the import CSV file is blank, then the matching value in the product list is overwritten as blank."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Column not present in the file at all:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If a non-required column isn't included in the import CSV file, but is included in the existing product list, then the value in the product list remains the same."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Both read on the Shopify help documentation for importing products, 2026-09-25.)&lt;/p&gt;

&lt;p&gt;The difference between them is the entire failure mode. Shopify's own illustration is a vendor: if the product currently has a vendor and the Vendor column in your file is empty for that row, the vendor is cleared.&lt;/p&gt;

&lt;p&gt;Now think about how a file actually reaches the import screen. You export 300 products. You open the file in a spreadsheet. You fix the descriptions, which is what you came to do. Somewhere in that session — a filter that hid rows, a sort that misaligned a block, a paste that landed one column to the left, a "clean up this column" that emptied it instead of the column next to it — a handful of cells that had values now don't. Every one of those cells is a live value you are about to clear, and the import will do it without complaint, because from Shopify's side an empty cell is an instruction.&lt;/p&gt;

&lt;p&gt;The asymmetry is what makes this hard to catch by eye. &lt;strong&gt;A wrong value looks wrong.&lt;/strong&gt; If a product ends up with the vendor of the product below it, you notice the first time you open a product page. &lt;strong&gt;An empty value looks like nothing at all&lt;/strong&gt; — and on the Products list view, which shows you a title, an image and a status, an emptied vendor or product type or tag set is completely invisible. You'd have to open the product to see the absence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which columns this actually hits
&lt;/h2&gt;

&lt;p&gt;The columns at risk are the ones that get emptied without anyone noticing, which means the boring organisational fields rather than the ones customers see. A blank title fails loudly. A blank product type doesn't fail at all.&lt;/p&gt;

&lt;p&gt;We read the public catalogues of 41 live Shopify storefronts — 20,604 products — and counted how often those organisational fields are empty in the wild:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Share of all products read&lt;/th&gt;
&lt;th&gt;Per-store median&lt;/th&gt;
&lt;th&gt;Stores with at least one&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Product type blank&lt;/td&gt;
&lt;td&gt;36.6%&lt;/td&gt;
&lt;td&gt;13.3%&lt;/td&gt;
&lt;td&gt;35 of 41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tags blank&lt;/td&gt;
&lt;td&gt;19.9%&lt;/td&gt;
&lt;td&gt;7.7%&lt;/td&gt;
&lt;td&gt;35 of 41&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;A few large catalogues carry most of it.&lt;/strong&gt; The pooled share and the per-store median differ by roughly 2.5x on both rows, and the gap means something specific: this isn't a condition spread evenly across every catalogue. A few stores with a lot of products carry most of the pooled number, while the typical store sits much lower. If you took the 36.6% alone you'd conclude everyone has this problem; the 13.3% says the median store mostly doesn't, and the stores that do, have it badly.&lt;/p&gt;

&lt;p&gt;These figures are a snapshot of what catalogues look like now, not a before-and-after of any particular import — we can say these fields are commonly empty, and that they're exactly the fields a CSV round trip can empty, but this measurement does not attribute a given store's blanks to a given import. And some of those blanks were never filled in the first place rather than wiped. Both fields have their own reasons for being empty, and we've written separately about &lt;a href="https://arvio.a.xyz/blog/shopify-product-type-missing?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_blog2" rel="noopener noreferrer"&gt;product type&lt;/a&gt; and &lt;a href="https://arvio.a.xyz/blog/shopify-tags-cleanup?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_blog3" rel="noopener noreferrer"&gt;tags&lt;/a&gt; as standalone problems. The reason they belong in &lt;em&gt;this&lt;/em&gt; article is narrower: they are the fields where a wipe produces no symptom, which is what makes them the right place to look after an import you're unsure about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The overwrite checkbox, and the error that is "nothing happened"
&lt;/h2&gt;

&lt;p&gt;The import screen offers an option to overwrite products with matching handles. Handle matching is how Shopify decides whether a row in your file is a new product or an edit to an existing one, so the checkbox is load-bearing — but not in the direction most people assume.&lt;/p&gt;

&lt;p&gt;Shopify's documentation says that "if the overwrite option isn't selected, then the products that match an existing handle are ignored during CSV import" (read 2026-09-25).&lt;/p&gt;

&lt;p&gt;Ignored. Not duplicated. If you are re-importing 300 products to fix their descriptions and you leave that box unticked, the import will report success and your descriptions will be exactly as they were. There is no error, no duplicate, no diagnostic — which is why people then spend an hour checking their spreadsheet for a formatting problem that doesn't exist.&lt;/p&gt;

&lt;p&gt;So the checkbox creates a fork with a bad outcome on each side if you get it wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unticked when you meant to edit:&lt;/strong&gt; nothing happens, and it looks like a file problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ticked when your file has stray blank cells:&lt;/strong&gt; everything happens, including the blank-column rule above, across every row and every column in the file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the case for making the file small. The overwrite option is exactly as dangerous as the number of columns and rows you hand it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You have now seen which columns do the damage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Checking every product a spreadsheet touched is the part that does not scale. Arvio takes the rule once, reads the live catalogue, and holds every proposed change until you say yes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=shopify-csv-import-errors&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_listing_mid" rel="noopener noreferrer"&gt;Install Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The five-minute pass that prevents the quiet errors
&lt;/h2&gt;

&lt;p&gt;None of this needs an app. It needs the file to be smaller than it currently is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Export only the products you're changing, not the catalogue.&lt;/strong&gt; If you are editing 300 products, a full-catalogue export puts every other product in the store inside the blast radius of the overwrite option for no benefit. Filter the Products list first, then export the selection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delete every column you are not deliberately editing — but not blindly.&lt;/strong&gt; Leaving a column out is normally safe: Shopify's documentation says "if a non-required column isn't included in the import CSV file, but is included in the existing product list, then the value in the product list remains the same" (read 2026-09-25). Keep the handle column so matching works, keep the columns you're actually editing, delete the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The exception that makes this dangerous, and it is documented.&lt;/strong&gt; Some columns depend on others. Shopify states: "If a non-required column is included in the import CSV file that relies on other column data not included in the file, then existing data is deleted or removed" (read 2026-09-25). Their own example is the one that catches people: "if the SKU column is included in the import CSV file, but not the Option1 value and Option1 name columns, then the product variant option is deleted." So cutting the file down is the right instinct, and it can still destroy variants if you keep a dependent column and drop what it depends on. If your products have variants, keep the Option columns together with anything variant-level (SKU, barcode, variant price) or leave that whole group out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then check the columns you kept for unintended blanks.&lt;/strong&gt; In the spreadsheet, filter each remaining column for empty cells. Every empty cell you find is a decision: either you meant to clear that value, or the cell lost its content somewhere in your editing session. The import cannot tell the difference between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity-check the row count and the alignment before you save.&lt;/strong&gt; Compare the number of data rows against the number you exported. If they differ, a filter was active or rows were dropped, and a dropped row is the one case where the import genuinely leaves the product alone — which is fine, but you should know it happened rather than discover it later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import the first ten rows as a test.&lt;/strong&gt; Save a copy of the file containing the header and ten products, import that with the overwrite option set the way you intend, and open two or three of those products afterwards. If the blank-column rule is going to bite, it bites on ten products instead of three hundred, and you still have the other 290 in their original state.&lt;/p&gt;

&lt;p&gt;That last step is the one people skip and the one that pays. Ten rows costs you two minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Column names: a real change, and a non-problem
&lt;/h2&gt;

&lt;p&gt;Column names get blamed for failed imports more than they deserve.&lt;/p&gt;

&lt;p&gt;The header row of an export we have on file reads &lt;code&gt;Handle,Title,Body (HTML),Vendor,Standardized Product Type,Custom Product Type,Tags,Published,...&lt;/code&gt; — the older naming, and a file with that header still imports. If you've been reusing a saved template for years, the names in it are not why a column didn't apply.&lt;/p&gt;

&lt;p&gt;What does matter is that the header has to match &lt;em&gt;something&lt;/em&gt; Shopify recognises, exactly. Column headers are matched literally, so a header with a stray leading space, a smart quote introduced by a spreadsheet, or a slightly different word is not a column Shopify knows about — it's an unrecognised column, and unrecognised columns don't do anything. This produces a confusing symptom: the import succeeds, and one field out of five didn't change, because that field's column was never read.&lt;/p&gt;

&lt;p&gt;The reliable way to get headers right is to not type them. Export from Shopify, edit the file you exported, and import that file back. You then know the headers are the ones that store's admin produces, whatever they happen to be called this year.&lt;/p&gt;

&lt;h2&gt;
  
  
  When an import has already gone wrong
&lt;/h2&gt;

&lt;p&gt;Everything above is about the file, before you press the button. If you already have a catalogue that went through a bad import, that's a different job with a different shape: you're no longer preventing damage, you're finding and repairing it, which means working out which products came from which import batch and scoring them. We wrote that up separately — see &lt;a href="https://arvio.a.xyz/blog/shopify-fix-catalog-after-import?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_blog5" rel="noopener noreferrer"&gt;how to clean up messy product data after a Shopify import&lt;/a&gt;, which includes a read-only script that groups your own catalogue by the day products were created so you can see which import to go back to first.&lt;/p&gt;

&lt;p&gt;Two things from that job are worth knowing before you start, because they change your approach here:&lt;/p&gt;

&lt;p&gt;The repair is very often another CSV import, which means all of the above applies again, with one extra hazard: you are now editing a file derived from a catalogue you already know is wrong, so the "is this cell empty on purpose?" question has a worse answer rate than usual. Export fresh, keep the file narrow.&lt;/p&gt;

&lt;p&gt;And if the damage is per-product judgement — 300 descriptions, 300 product types that each need a different value — the CSV route moves the work into a spreadsheet without making it smaller. That's a decision about where the time goes, not a technical limitation of the importer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we can and can't tell you here
&lt;/h2&gt;

&lt;p&gt;The documented behaviours in this article — the blank-column rule, the absent-column rule, the overwrite-checkbox behaviour, the 15 MB limit — come from Shopify's own help documentation, quoted with the date we read it. Those are quotations, not our measurements.&lt;/p&gt;

&lt;p&gt;The catalogue figures come from our own read of 41 public storefronts, described in the method note below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=shopify-csv-import-errors&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; It reads what an import left behind and drafts the repair per product, for you to approve.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why did my Shopify CSV import say it succeeded but nothing changed?
&lt;/h3&gt;

&lt;p&gt;The most common cause is the overwrite option. Shopify's documentation states that when the overwrite option isn't selected, products matching an existing handle are ignored during CSV import — so an import of edits to existing products completes, reports success, and applies nothing. Check the handle column matches the live handles exactly, and check that box if you intend to edit existing products.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does an empty cell in a Shopify import CSV delete the existing value?
&lt;/h3&gt;

&lt;p&gt;Yes, if that column is present in the file. Shopify documents that a blank non-required column in the import file overwrites the matching value in the product list as blank. A column that isn't in the file at all is left alone. This is why deleting the columns you aren't editing is safer than leaving them in and empty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will importing a CSV with an existing handle create a duplicate product?
&lt;/h3&gt;

&lt;p&gt;Not from the overwrite setting. With the option off, matching products are ignored rather than duplicated. Duplicates come from handles that don't match the live ones — a changed title that regenerated the handle, or a handle column edited in the spreadsheet —.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the file size limit for a Shopify product CSV?
&lt;/h3&gt;

&lt;p&gt;Shopify's documentation gives 15 MB, and recommends splitting into multiple smaller files if the upload errors or times out. Splitting also limits how much of your catalogue a single mistake can reach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do old Shopify CSV column names still work?
&lt;/h3&gt;

&lt;p&gt;Yes. An export file using the older header names still imports, so a saved template from a previous year is not the reason a column failed to apply. The thing to check is whether each header matches a name Shopify recognises exactly — a stray space or a smart quote makes a column unrecognised, and unrecognised columns are silently ignored.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I check an import before running it on my whole catalogue?
&lt;/h3&gt;

&lt;p&gt;Export only the products you're changing, delete every column you aren't editing, filter the remaining columns for empty cells and confirm each one is intentional, then import a copy containing just the header and ten products. Open two or three of those products afterwards. If something is going to be wiped, it gets wiped on ten products instead of the whole batch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which fields should I check after an import that might have gone wrong?
&lt;/h3&gt;

&lt;p&gt;Start with the organisational fields that produce no visible symptom — product type, tags, vendor — because the Products list view shows a title, an image and a status, none of which reveal an emptied field. Across 41 public storefronts we read, product type was blank on 36.6% of products pooled with a per-store median of 13.3%, and tags on 19.9% pooled with a median of 7.7%.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Documentation.&lt;/strong&gt; The rules about blank columns, absent columns, the overwrite option and the file size limit are quoted from Shopify's public help documentation on importing products with CSV, with the date each was read. We did not run a controlled import to reproduce them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Catalogue figures.&lt;/strong&gt; 41 live Shopify storefronts, 20,604 products, read 2026-08-26 via each store's public &lt;code&gt;products.json&lt;/code&gt; endpoint; figures computed 2026-09-21. No page was truncated. Everything here came from endpoints any browser can fetch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whether it looks like you.&lt;/strong&gt; The stores came at random from a public list of owners who posted their own URL on the Shopify Community's Store Feedback board asking for critique. Stores that ask for feedback skew newer and smaller, and the largest bias is survivorship: candidate domains that no longer resolved, returned an error, or were password-protected were excluded, so what remains is the set that is still trading. Both figures above are given pooled and as a per-store median precisely because the two disagree — a pooled percentage over 20,604 products is dominated by the largest catalogues, and the median is closer to what a typical store in this list looks like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What isn't here.&lt;/strong&gt; We did not measure whether any particular store's blank fields were caused by an import. The figures establish that these fields are commonly empty and that a CSV round trip can empty them without symptom.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/shopify-csv-import-errors?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/shopify-csv-import-errors&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=shopify-csv-import-errors_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Write a Product Description (Check Your Catalogue First)</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Fri, 25 Sep 2026 14:07:24 +0000</pubDate>
      <link>https://dev.to/arvio/how-to-write-a-product-description-check-your-catalogue-first-1ngc</link>
      <guid>https://dev.to/arvio/how-to-write-a-product-description-check-your-catalogue-first-1ngc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/how-to-write-product-description?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/how-to-write-product-description&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most advice on this topic assumes you are looking at an empty box. On the storefronts we read, that is rarely the situation: the box usually has something in it, and the problem is who else has the same something.&lt;/li&gt;
&lt;li&gt;The finding we had not published: among the stores that repeat a description at all, &lt;strong&gt;33&lt;/strong&gt; have &lt;strong&gt;half or more&lt;/strong&gt; of their read catalogue on repeated text, and &lt;strong&gt;4&lt;/strong&gt; are at &lt;strong&gt;100%&lt;/strong&gt;: every product we could read was sharing its description with another product. In three of those four it was several shared blocks rather than one.&lt;/li&gt;
&lt;li&gt;This is not an artefact of tiny shops. Of those 33, only &lt;strong&gt;one&lt;/strong&gt; had a catalogue under five products, and &lt;strong&gt;29&lt;/strong&gt; had ten or more.&lt;/li&gt;
&lt;li&gt;So the useful first move is diagnosis, not drafting. The advice that helps a store at 8% repeated is different from the advice that helps a store at 100%, and you cannot tell which you are from inside the admin.&lt;/li&gt;
&lt;li&gt;Everything below came from endpoints any browser can fetch, on 225 live storefronts read on 2026-09-05.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You can measure this before you write a word&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvio is an AI store operator. It runs this same count against your live catalogue, then drafts a replacement for each product it flags. Nothing is written until you approve it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=how-to-write-product-description&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Find out which problem you have
&lt;/h2&gt;

&lt;p&gt;Writing guides are written for a person sitting in front of an empty description box. That person exists. But when we read 225 live storefronts, the description box was usually not empty, and the thing that was actually wrong with a catalogue was almost never visible from any single product page.&lt;/p&gt;

&lt;p&gt;The admin does not surface it either. The product list shows one row per product, so a description pasted onto forty products looks exactly like forty products that each have a description. The count is there if you go looking for it, but nothing puts it in front of you.&lt;/p&gt;

&lt;p&gt;So start by counting: &lt;strong&gt;how many of my products are already carrying the same block of text&lt;/strong&gt;? The answer changes what you should do next.&lt;/p&gt;

&lt;p&gt;One warning before you read the number, because it decides whether any of this applies to you. If you publish each colourway as its own product — the same shoe in twelve colours, twelve product pages — those twelve legitimately share a description, and a count like this will call all twelve repeated. That is not a defect, and a store built that way can score very high here while being perfectly well run. Before acting on your percentage, open two or three of the products the count flags: if they are the same item in different colours, ignore the number. It is telling you about your catalogue structure, not about your descriptions.&lt;/p&gt;

&lt;p&gt;⚠️ A spreadsheet export will not give you this number, even though it looks like it should. Shopify's product CSV is one row per &lt;em&gt;variant&lt;/em&gt;, and &lt;code&gt;Body (HTML)&lt;/code&gt; is filled in only on each product's first row, so sorting that column stacks up mostly blanks rather than duplicates. Counting those blanks would tell you the opposite of the truth.&lt;/p&gt;

&lt;p&gt;This command gives the number in a few seconds. It is read-only, needs no login and no app, and writes nothing anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
# save as dupes.py, then:  python3 dupes.py your-store.com
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;usage: python3 dupes.py your-store.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;shop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;rstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                                  &lt;span class="c1"&gt;# 20 x 250 = 5,000 products
&lt;/span&gt;    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;shop&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/products.json?limit=250&amp;amp;page=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;desc-check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;batch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;products&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                         &lt;span class="c1"&gt;# not every store publishes this
&lt;/span&gt;        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;could not read &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;shop&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/products.json (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;).&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Password-protected and unopened stores do not serve it.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;                                    &lt;span class="c1"&gt;# tags out, whitespace collapsed
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\s+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;[^&amp;gt;]+&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;descs&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body_html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;filled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;descs&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;repeated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;in_dup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;filled&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;repeated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;products read        &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;empty description    &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;descs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;repeated text        &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;in_dup&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;in_dup&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;% of catalogue)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;most_common&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;   x&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The number that matters is the percentage on the third line. Everything in this article hangs off it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What that percentage looked like on 225 stores
&lt;/h2&gt;

&lt;p&gt;We ran the same two tests across every product we could read on 225 live storefronts. The prevalence figures — how common repetition is, how long descriptions run, how few are empty — we published separately in &lt;a href="https://arvio.a.xyz/blog/product-description-examples-shopify?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_blog2" rel="noopener noreferrer"&gt;product description examples&lt;/a&gt;, and they are the context for this piece rather than its subject. The short version of that prior work: repetition is common, and the empty box is not where the damage is.&lt;/p&gt;

&lt;p&gt;What that piece did not break out is &lt;strong&gt;how bad it gets inside the stores it affects&lt;/strong&gt;. That is the distribution below.&lt;/p&gt;

&lt;p&gt;Of the 111 storefronts carrying at least one repeated description, the share of their read catalogue sitting on repeated text fell out like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Share of catalogue on repeated text&lt;/th&gt;
&lt;th&gt;Stores&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100% — every product read shared its text with another&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;At least 75%, but not all&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50–74%&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25–49%&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Under 25%&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every share here is a share of &lt;strong&gt;what we could read&lt;/strong&gt;, not of the whole catalogue: we read up to 50 products per store, and 126 of the 225 stores hit that cap. The Method section at the end says exactly which findings that touches.&lt;/p&gt;

&lt;p&gt;Read the top three rows together: &lt;strong&gt;33 stores at half the catalogue or worse&lt;/strong&gt;. That is roughly a third of the affected group. The median affected store sits at 30.3%, so the group is not uniformly bad, it is split. Most affected stores have a containable problem. A third of them have a structural one.&lt;/p&gt;

&lt;p&gt;The four at 100% are the ones worth pausing on. On those stores, every product we read was carrying text that also appears on another product. It is not always one block copied everywhere: the number of distinct repeated descriptions was 5, 3, 2 and 1 across the four. Only the last is the case people picture. Whatever they sell, the description field has stopped distinguishing any of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  It is not a small-catalogue artefact
&lt;/h3&gt;

&lt;p&gt;A store with three products trivially hits 100%, so we checked whether the 33 are just tiny shops.&lt;/p&gt;

&lt;p&gt;Of the 33 stores at 50% or more, exactly &lt;strong&gt;one&lt;/strong&gt; had a catalogue under five products. &lt;strong&gt;29 of the 33&lt;/strong&gt; had ten or more. These are stores with enough products that nobody is going to notice the repetition by scrolling.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The measurement is the part that does not scale&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have now seen the check. Running it once tells you where you stand; the work after that is one product at a time, and that is the part that does not scale. Arvio drafts each replacement for you to approve or reject individually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=how-to-write-product-description&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_listing_mid" rel="noopener noreferrer"&gt;Install Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How to write one, once you know which problem you have
&lt;/h2&gt;

&lt;p&gt;The writing advice is the same everywhere and it is mostly right. What changes with your percentage is &lt;strong&gt;which products you point it at, and in what order&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A description earns its place by answering the questions a product page leaves open. In practice that is four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What it physically is.&lt;/strong&gt; Material, dimensions, weight, what is in the box. This is the part a shared description always gets wrong, because it was written for a different object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who it is for, stated as a situation.&lt;/strong&gt; Not "perfect for everyone", but the specific occasion, room, skin type, riding style, whatever your category's axis is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The one objection that stops the sale.&lt;/strong&gt; Sizing, compatibility, care, shipping restrictions. You already know what it is for your category, because you answer it in email every week.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What makes this one different from the next one in the collection.&lt;/strong&gt; This is the sentence that repeated text structurally cannot contain.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last point is the whole reason the percentage matters. A shared description can be well written, on-brand, and persuasive, and still fail, because the job of a product description is to distinguish one product from the others beside it, and a description on forty products distinguishes nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to start, by your number
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Under 25%.&lt;/strong&gt; Your repetition is probably clustered in one or two collections: variants that were duplicated, or a seasonal range someone filled in quickly. Find the clusters with the script above (the &lt;code&gt;x4&lt;/code&gt;, &lt;code&gt;x12&lt;/code&gt; lines), rewrite those, and then treat the rest of the catalogue as a normal writing task: highest-traffic products first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;25–49%.&lt;/strong&gt; Do not start at the top of the product list. Start with the repeated groups, largest group first. One rewrite there fixes the most pages, and it is the fastest way to move the number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;50% and above.&lt;/strong&gt; Writing product by product will not close this in any reasonable amount of time. The descriptions need to be generated from the product data you already hold (vendor, type, options, variants) and then reviewed, rather than composed from scratch one at a time. On the mechanics of applying changes across a catalogue, we have a &lt;a href="https://arvio.a.xyz/blog/bulk-edit-product-descriptions-shopify?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_blog4" rel="noopener noreferrer"&gt;separate piece on editing descriptions at catalogue scale&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;At or near 100%.&lt;/strong&gt; Treat the current description as absent. It is carrying no product-specific information, so there is nothing to preserve and nothing to edit around. The fastest path is a fresh draft per product, reviewed before it goes live.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we did not measure
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We read up to 50 products per store, and 126 of the 225 hit that cap.&lt;/strong&gt; Over half the sample is therefore a 50-product slice rather than a whole catalogue, including 23 of the 33 stores at 50% or worse and two of the four shown at 100%. Every percentage here is a share of what we read. A store shown at 100% has every product we read sharing text with another product we read; we cannot claim that about products we did not read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We did not measure whether any of this costs sales.&lt;/strong&gt; No traffic, no conversion, no revenue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Of the 230 hosts in the frame, 5 were unreadable&lt;/strong&gt;. The endpoint did not return a usable catalogue. Those are n/a, excluded from every denominator above, and are not counted as zero.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does length tell me anything about whether mine are working?
&lt;/h3&gt;

&lt;p&gt;Not much, and it is the wrong thing to measure first. A short description that answers the sizing question beats a long one that does not, and a long one shared across forty products is worse than either. We looked at the length spread separately in &lt;a href="https://arvio.a.xyz/blog/product-description-examples-shopify?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_blog5" rel="noopener noreferrer"&gt;product description examples&lt;/a&gt;; for this article, how many products share the text matters more than how long it runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it actually a problem if two products share a description?
&lt;/h3&gt;

&lt;p&gt;Two, on genuinely near-identical products, is not much of a problem. The failure mode this article is about is scale: the point where a description covers so many products that it cannot be describing any of them. The script above tells you which situation you are in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I write descriptions myself or have a model draft them?
&lt;/h3&gt;

&lt;p&gt;What matters is what the draft is written against. A draft generated from the product's own data (its variants, its options, its type) can be product-specific. A draft generated from the product title alone will read like the shared description you are trying to replace. Either way, review before publishing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does every product need its own description?
&lt;/h3&gt;

&lt;p&gt;Every product that you expect someone to arrive at directly needs something on the page that answers the physical questions. What you do not need is the same paragraph on all of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will rewriting descriptions improve my search ranking?
&lt;/h3&gt;

&lt;p&gt;We did not measure that, and we are not going to claim it. The argument in this article is narrower and does not depend on search: a description that is on forty products is not telling a shopper which of the forty they are looking at.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where do I start if every product is sharing text?
&lt;/h3&gt;

&lt;p&gt;Highest-traffic products first, one at a time, reviewed before each goes live. The point of measuring first is that you now know the order matters. At that share of the catalogue, you are rebuilding rather than editing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample.&lt;/strong&gt; 225 live Shopify storefronts, read on 2026-09-05, taken at random from a public list of stores whose owners had posted their own URL on the Shopify Community's Store Feedback board. Everything here came from endpoints any browser can fetch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The funnel.&lt;/strong&gt; 230 hosts attempted, 5 did not return a usable catalogue and were excluded, leaving 225 stores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we read.&lt;/strong&gt; Up to 50 products per store from the public products endpoint. Description text is the description field with HTML tags stripped and whitespace collapsed. Two products count as sharing a description when that normalised text matches exactly; empty descriptions are counted as empty, not as copies of each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How severity is calculated.&lt;/strong&gt; For each store with at least one repeated description, severity is the number of its read products carrying repeated text, divided by the number of products we read from that store. Stores with no repetition are not in the distribution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whether it looks like you.&lt;/strong&gt; Stores that ask for feedback on a public board skew newer and smaller than Shopify as a whole. The largest bias is survivorship: the frame started from a larger list of candidate domains, and the ones that no longer resolved, returned errors, or were password-protected were dropped before we read anything. What is left is the stores still trading.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=how-to-write-product-description&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; It finds the products sharing text and drafts each replacement for your approval.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/how-to-write-product-description?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/how-to-write-product-description&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=how-to-write-product-description_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>One Instruction vs One Product: What a Run Actually Is</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:14:43 +0000</pubDate>
      <link>https://dev.to/arvio/one-instruction-vs-one-product-what-a-run-actually-is-1i6o</link>
      <guid>https://dev.to/arvio/one-instruction-vs-one-product-what-a-run-actually-is-1i6o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/arvio-run-not-product?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-run-not-product&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You are not buying products. You are buying &lt;strong&gt;instructions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One sentence you type — "rewrite the description for this product," "fix every listing in this collection," "go through the whole spring range" — is one run. One AI task. One line on your bill, whether it touches one product or a batch you pick.&lt;/p&gt;

&lt;p&gt;That is the whole pricing model. Everything below is the table, one real run, and the part we have not measured.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three plans, in credits and AI tasks
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Monthly allowance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;800 credits/mo (~80 AI tasks)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Growth&lt;/td&gt;
&lt;td&gt;4,000 credits/mo (~400 AI tasks)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;10,000 credits/mo (~1,000 AI tasks)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the right-hand column and ignore the left one for now. An AI task is one instruction you gave: when you sit down and decide "today I want the seasonal copy sorted," that decision is the unit — not the number of rows it happens to touch. Credits are the meter underneath, and the conversion between them is in the FAQ.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-run-not-product&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What one real run looks like
&lt;/h2&gt;

&lt;p&gt;Here is a run on our own demo store, start to finish.&lt;/p&gt;

&lt;p&gt;The instruction was one sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Rewrite the product description for one product only: Acacia Round Tray. Leave every other product untouched.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstp9lxhejfh4osvj2ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstp9lxhejfh4osvj2ln.png" alt="One instruction, typed once, with the scope written into the sentence" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is the entire input. No spreadsheet, no column mapping, no rules engine. The scope lives inside the sentence — "one product only," "leave every other product untouched" — because that is how you would say it to a person.&lt;/p&gt;

&lt;p&gt;The catalog had 68 products before the run and 68 products after it. Nothing was created, nothing was deleted. Exactly 1 product came out different: the description on Acacia Round Tray went from 62 characters to 364 characters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" alt="Sixty-eight products before the run, sixty-eight after, one of them different" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That before-and-after count is the part worth pausing on. A scoped instruction that says "leave every other product untouched" produced a catalog where every other product was, in fact, untouched. The blast radius matched the sentence.&lt;/p&gt;

&lt;p&gt;Be clear about how much one run can carry, though. This is a single narrow instruction on a 68-product store we own, from a prompt we wrote ourselves. It shows you what the billing unit is and that the scope held on that run — it is not a sample, and nothing here tells you what a wide instruction costs, which is the gap named further down. The version of this that would convince us is the one you run on your own catalog.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff80pulrpofmfkgrixemh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff80pulrpofmfkgrixemh.png" alt="The result card restates what changed and links into Shopify Admin" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the run finishes, you get a card that restates what changed and links straight into your Shopify Admin, so you can look at the live product page yourself rather than taking our word for it. If you want the longer version of how a run is assembled and reported, &lt;a href="https://arvio.a.xyz/blog/what-arvio-actually-does?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_blog2" rel="noopener noreferrer"&gt;we walked through the whole loop in a separate piece&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "per product" is the wrong mental model
&lt;/h2&gt;

&lt;p&gt;Now change one word in that instruction. Instead of "one product only: Acacia Round Tray," write "every product in the Tableware collection."&lt;/p&gt;

&lt;p&gt;It is still one instruction. One run. One AI task. What we cannot tell you is what that wider run draws off the meter in credits — that is the measurement we have not published, and it has its own section below rather than a footnote, because it is the number you would most want before choosing a plan.&lt;/p&gt;

&lt;p&gt;From the product page itself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;One product, a batch you pick, or all of them — you choose the scope&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the part that trips people up when they come from tools priced per row. Per-row pricing trains you to think about your catalog as a meter that ticks. You start rationing: maybe I only fix the top sellers, maybe I skip the variants, maybe I do half now and half next month. The rationing has nothing to do with what your store needs — it is an artifact of how somebody chose to charge you.&lt;/p&gt;

&lt;p&gt;Arvio bills the decision, not the rows. The unit you get charged for is the unit you were already thinking in. You wanted the spring collection sorted; that is one thing you wanted; it shows up as one thing on the meter.&lt;/p&gt;

&lt;p&gt;Practically, that changes how you should scope your work. Under per-row pricing, the instinct is to keep scopes tiny. Here the instinct should be the opposite: decide what "done" looks like for a whole slice of the catalog, then say that in one sentence. Splitting the same work into a dozen careful little instructions is a dozen AI tasks instead of one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The measurement we have not published
&lt;/h2&gt;

&lt;p&gt;If one instruction sweeps a whole collection instead of a single product, what does that cost in credits? We have not measured that in a way we are willing to print. The &lt;code&gt;~80 AI tasks&lt;/code&gt; on the Starter line is the conversion for a typical task, and a task that sweeps a large batch is not the same shape as one that touches a single product.&lt;/p&gt;

&lt;p&gt;So there is no arithmetic here that turns 800 credits into 800 products. Any per-product cost you derive from that table is a figure we did not give you.&lt;/p&gt;

&lt;p&gt;To find your own number, run one small scoped instruction, the way we ran the Acacia Round Tray one, and watch what it draws down. Then run a slightly wider one and watch again. That is measured on your store instead of on our hypothetical, and you can check the results in Shopify Admin between each step.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-run-not-product&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_listing_mid" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When you should not buy this
&lt;/h2&gt;

&lt;p&gt;If your catalog is small and rarely changes, you don't need us.&lt;/p&gt;

&lt;p&gt;That is the official line and we mean it literally. A store with a couple of dozen products where you wrote every description yourself and change them twice a year does not have a problem that an AI Store Operator solves. You will spend an afternoon and be done. Buying a monthly allowance of instructions to use twice a year is a bad trade, and there is no version of the plan table above that makes it a good one.&lt;/p&gt;

&lt;p&gt;A few other cases where you should probably wait:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You do not yet know what "good" looks like for your store.&lt;/strong&gt; Arvio executes decisions. If the decision itself is unsettled — you are still figuring out your voice, your positioning, how you want the category pages to read — the bottleneck is not execution speed. Work that out on a handful of products by hand first, then hand over the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need every single output reviewed before it goes live anyway.&lt;/strong&gt; Some merchants operate in categories where each line of copy has to pass a compliance read. That review is still your job, and if reviewing takes as long as writing, the run is not buying you much.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your problem is data you do not have.&lt;/strong&gt; If the reason your listings are thin is that nobody ever collected the material — measurements, ingredients, sourcing details — then no instruction fills that in. It is a supplier problem wearing a copywriting costume.&lt;/p&gt;

&lt;p&gt;The merchants this actually fits are the ones who already know exactly what needs to happen across a few hundred product pages and simply cannot sit down and do them one at a time. That is the gap. &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_blog4" rel="noopener noreferrer"&gt;We have written about what the fix looks like when it lands in your store&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-run-not-product&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; One instruction, whatever scope you choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;If one instruction covers a whole collection, is that one AI task or one per product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One instruction is one run. The scope lives inside the sentence you write — one product, a batch you pick, or all of them. What we have not published is how credit consumption scales as that scope widens, so if you are planning around a large sweep, run a small one first and watch your balance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between credits and AI tasks?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Credits are the underlying meter and AI tasks are the human-readable conversion of it. Starter carries 800 credits/mo (~80 AI tasks), Growth 4,000 credits/mo (~400 AI tasks), Pro 10,000 credits/mo (~1,000 AI tasks). The conversion is approximate, which is the reason for the tilde.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I know it only touched what I told it to touch?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write the scope into the instruction and then check the result. In the run above, the sentence said "one product only" and "leave every other product untouched," and the catalog went from 68 products to 68 products with exactly 1 of them changed. The result card links into Shopify Admin so you can open the product and read what is live rather than trusting a summary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I see what changed before it goes live?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The result card restates what the run did and points you at the affected products in your own Admin. Reading the output is part of the workflow, not an optional extra — especially on the first few runs, while you are calibrating how much scope to hand over at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I split a big job into several small instructions to be safe?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Splitting is a reasonable way to build confidence early, and it is how we would suggest starting. Just be aware of the trade: several careful instructions are several AI tasks, where the same work described in one sentence is one. Once you trust the scoping, widen it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why won't you just tell me the cost per product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because we have not measured it, and a number we invented would be worse than no number. We can tell you the plan allowances and we can tell you the billing unit is the instruction. The exchange rate between a wide instruction and a narrow one is a gap in what we have published, and filling it with division would be filling it with fiction.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/arvio-run-not-product?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-run-not-product&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-run-not-product_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Four Shapes of Catalogue Tool, and What Each One Asks of You</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:14:33 +0000</pubDate>
      <link>https://dev.to/arvio/four-shapes-of-catalogue-tool-and-what-each-one-asks-of-you-1mf4</link>
      <guid>https://dev.to/arvio/four-shapes-of-catalogue-tool-and-what-each-one-asks-of-you-1mf4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/arvio-three-tool-shapes?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-three-tool-shapes&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are four shapes a tool can take when your catalogue has problems in it. An &lt;strong&gt;audit&lt;/strong&gt; tells you where they are. A &lt;strong&gt;bulk editor&lt;/strong&gt; lets you change many things at once. A &lt;strong&gt;rule engine&lt;/strong&gt; lets you write the logic once and apply it everywhere. A &lt;strong&gt;draft-then-approve&lt;/strong&gt; tool writes the specific change and stops for your answer.&lt;/p&gt;

&lt;p&gt;They are not four quality tiers, and picking badly is expensive in a way that has nothing to do with whether the tool is good.&lt;/p&gt;

&lt;p&gt;The useful question is not "which is best" but &lt;strong&gt;what does this shape make me spend?&lt;/strong&gt; Attention, typing, rule maintenance, or per-item judgment — four different budgets, and most stores have a lot of only one. What follows argues from how those four shapes divide the labour, not from a trial: we have not run one catalogue through four tools and compared the outcomes.&lt;/p&gt;

&lt;p&gt;If you only have a minute, the whole decision is one question asked twice. &lt;strong&gt;Is the right change the same for every affected product?&lt;/strong&gt; If yes, you want a bulk editor — or a rule engine, if it will still be the same change a year from now and somebody will own the rules. If no, &lt;strong&gt;do you care what each one says?&lt;/strong&gt; If yes, you are in the fourth shape and the price is that you look at them; if no, an audit will at least tell you the size of the problem. The longer version, with the edge cases, is further down.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four shapes side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shape&lt;/th&gt;
&lt;th&gt;What it gives you&lt;/th&gt;
&lt;th&gt;What it asks of you&lt;/th&gt;
&lt;th&gt;When it's the right one&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audit / report&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A list of what's wrong, with locations&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Attention, then all the work.&lt;/strong&gt; The findings are yours to act on&lt;/td&gt;
&lt;td&gt;You don't yet know what's broken, or you need a defensible inventory of it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bulk editor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The ability to change many records in one pass&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Typing and decisions.&lt;/strong&gt; You still supply what each change should be&lt;/td&gt;
&lt;td&gt;The change is mechanical and uniform — a prefix, a price rule, a field swap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rule / template engine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Consistency, applied automatically to everything matching&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Rule maintenance forever.&lt;/strong&gt; Rules drift, collide, and need owners&lt;/td&gt;
&lt;td&gt;Your catalogue is genuinely homogeneous — hundreds of SKUs in one shape&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Draft-then-approve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The specific change, already written, waiting on you&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Per-item judgment.&lt;/strong&gt; You look at each one&lt;/td&gt;
&lt;td&gt;Items differ enough that the right change is different each time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-three-tool-shapes&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6sduh5m47y4jg63fb04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6sduh5m47y4jg63fb04.png" alt="Four ways to fix a catalogue, and what each one asks of you" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The four shapes differ less in what they can do than in which of your resources they consume.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Shape by shape
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The audit
&lt;/h3&gt;

&lt;p&gt;An audit reads your catalogue and returns findings: which products have thin descriptions, which have no product type, which categories are empty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is genuinely the right tool when you don't know what's wrong&lt;/strong&gt; — which is most stores, most of the time, especially after a migration or a stretch where several people had admin access and nobody kept notes. You cannot prioritise a catalogue you haven't measured, and turning vague unease into a shape and a count is real work somebody has to do.&lt;/p&gt;

&lt;p&gt;What it asks of you is attention, and then everything else. The output is a list, and a list is a set of jobs assigned to you. The finding "this description is thin" does not contain the replacement description. Locating was the cheap half.&lt;/p&gt;

&lt;p&gt;The failure mode is worth naming: an audit that returns the same count next month is not broken. It finished its job and handed you yours. More on &lt;a href="https://arvio.a.xyz/blog/why-fix-not-report?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_blog2" rel="noopener noreferrer"&gt;why a report leaves the expensive half with you&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is also a case where the list &lt;em&gt;is&lt;/em&gt; the deliverable and nothing further is needed — a migration check, a pre-launch sweep, an answer to "did the import land cleanly." There you want findings, not changes, and a tool that started editing would be the wrong tool entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  The bulk editor
&lt;/h3&gt;

&lt;p&gt;A bulk editor lets you select a set of products and apply a change to all of them in one pass, instead of opening records one at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When the change is mechanical and uniform, this is the correct tool and nothing else comes close.&lt;/strong&gt; Adding a supplier prefix to a batch of SKUs. Moving products into a category. Raising prices on a vendor's line. Clearing a field that shouldn't have been populated. In all of these the right change is &lt;em&gt;the same change&lt;/em&gt; for every row, and you already know what it is. A tool that stopped to ask about each one would be actively worse — it would convert a single decision into hundreds of identical confirmations.&lt;/p&gt;

&lt;p&gt;What it asks of you is typing and decisions. It removes the repetition of &lt;em&gt;applying&lt;/em&gt; a change, not the work of &lt;em&gt;deciding what the change should be&lt;/em&gt; — and when the right value differs per product, it can't help with that at all. The efficiency comes entirely from the changes being identical. Feed it a job where every row needs a different answer and you've bought a faster way to type the same amount.&lt;/p&gt;

&lt;p&gt;The boundary is easy to test before you commit. Ask whether you could hand the job to someone who has never seen the catalogue, with one sentence of instruction. If yes, it's a bulk edit and you should do it that way. If the instruction has to end with "…and use your judgment on the rest," you've left the shape.&lt;/p&gt;

&lt;h3&gt;
  
  
  The rule or template engine
&lt;/h3&gt;

&lt;p&gt;A rule engine lets you write the logic once — &lt;em&gt;if a product has no description, compose one from the title, material, and category&lt;/em&gt; — and applies it to everything that matches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When your catalogue is truly homogeneous, this is unbeatable.&lt;/strong&gt; Hundreds of SKUs in the same family, differing in size and colour, described by the same fields in the same order: a template will produce better and more consistent output than a person typing each one, and it keeps producing it as new variants arrive. Consistency is the whole product, and here consistency is what you want.&lt;/p&gt;

&lt;p&gt;The cost has two parts, and the second surprises people.&lt;/p&gt;

&lt;p&gt;The first is sameness. A template produces template output. Where every product genuinely is a variation on one thing, nobody minds. In a mixed catalogue, it makes your differentiated products read like your commodity ones.&lt;/p&gt;

&lt;p&gt;The second is &lt;strong&gt;maintenance, which is permanent.&lt;/strong&gt; A rule set is code, and it needs an owner. Rules drift out of alignment as you add lines that don't fit the shape, they collide in ways that only surface on particular products, and whoever wrote them eventually leaves. The cost isn't the afternoon spent writing the rules. It's every month after that.&lt;/p&gt;

&lt;p&gt;That cost is often worth paying. A rule that stays correct is the cheapest thing in this comparison per product touched, and it gets cheaper as the catalogue grows — the opposite of everything else here. The question is only whether your catalogue actually holds still enough for a rule to stay correct.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fourth shape
&lt;/h3&gt;

&lt;p&gt;The fourth shape sits in a specific gap: what do you do when the right change genuinely differs per item, but you don't have time to compose each one?&lt;/p&gt;

&lt;p&gt;An audit won't do it: reporting is the whole of what it does. Neither will a bulk editor, because you are the one supplying the words it applies. And a rule engine is built on the premise that one rule fits everything, which is exactly what isn't true here.&lt;/p&gt;

&lt;p&gt;So: &lt;strong&gt;compose the specific change for the specific item, then stop and show it to the person.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio is an AI store operator.&lt;/strong&gt; It reads your live catalogue, writes the actual change for one actual product, and then does nothing until you say so.&lt;/p&gt;

&lt;p&gt;There is also a difference the four-way table above does not capture, because it is not a difference in shape: who speaks first. The other three wait for you to start — you go run the audit, you go select the batch, you go write the rule. This one reads every product nightly and writes each fix with nothing for you to ask or prompt. What arrives in the morning is a set of drafts you did not have to think to request. The change arrives written — not described, not suggested — in an editable box you can change before agreeing to it.&lt;/p&gt;

&lt;p&gt;The scheduled half of that — the reading it does overnight, without you — is the product's own scope, listed under Shopify's &lt;code&gt;Scheduled tasks&lt;/code&gt; category. The run we recorded below is not that: it is a single product we triggered by hand, and it is the only part of this we measured ourselves.&lt;/p&gt;

&lt;p&gt;On a run we recorded against our own demo store, a product whose stored description was 62 characters came back with a replacement already drafted. Nothing had been written to the store yet. (The replacement ran 361–364 characters, depending on whether you count the markup.) What was on screen was a confirmation card, and its scope line read:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only this product will be updated — all others left untouched.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After the button, the result card says &lt;code&gt;✓ Description updated&lt;/code&gt;, and then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This action can be undone. Let me know if you'd like to revert it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sequence — written, scoped, refusable, reversible — is the shape this article has been describing. One run on our own store is enough to show you what the sequence looks like; it is not evidence about how good the drafts are, how it behaves on a catalogue we have never seen, or what happens on the two-hundredth card. Those are the questions worth asking, and a single recorded run does not answer any of them. We've walked through &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_blog3" rel="noopener noreferrer"&gt;what one of these changes looks like on screen&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-three-tool-shapes&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_listing_mid" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What this shape costs
&lt;/h2&gt;

&lt;p&gt;It costs you per-item judgment. You have to look at each one.&lt;/p&gt;

&lt;p&gt;That is a real tax. The approval is the point of the design, which makes it the bottleneck, and the bottleneck does not shrink as the catalogue grows.&lt;/p&gt;

&lt;p&gt;We can put one honest number against the machine's half of that and none against yours. In the run we recorded, Arvio's own progress line read &lt;code&gt;Plan complete 39s&lt;/code&gt; before the card appeared. Your half is the part that scales: reading a draft properly is a minute or two, and two hundred of them is not two hundred minutes of the same quality — attention degrades, which is the actual failure mode of this shape. We have not measured where that degradation starts, and we are not going to quote a products-per-hour figure we did not measure.&lt;/p&gt;

&lt;p&gt;So, plainly: &lt;strong&gt;if your changes are mechanical and uniform, a bulk editor is faster and you should use that.&lt;/strong&gt; Not "faster in some cases" — faster, straightforwardly. Approving several hundred identical prefix additions is a worse design than one selection applied once. The same goes for templates on a catalogue that genuinely is one family in many variations.&lt;/p&gt;

&lt;p&gt;The gap this shape fits is narrow: items that differ enough that the right change differs, in a catalogue where you still care what each one says.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to tell which one you need
&lt;/h2&gt;

&lt;p&gt;Four questions, answerable without installing anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Do you know what's wrong?&lt;/strong&gt; If no, start with an audit regardless of what comes next. You can't choose between the other three without knowing the shape of the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Is the right change the same for every affected product?&lt;/strong&gt; If yes, you want a bulk editor. Write the change down: if it fits in one sentence that applies to every row, it's uniform. If you find yourself writing "…except for the ones where," it isn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Would one template produce acceptable output everywhere?&lt;/strong&gt; If yes, &lt;em&gt;and&lt;/em&gt; somebody will own the rules a year from now, a rule engine is the efficient answer. Both halves matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Does the right change differ per item, and do you care what each says?&lt;/strong&gt; Then you're in the fourth shape, and the price is that you look at them.&lt;/p&gt;

&lt;p&gt;Note what isn't on that list: which tool is best. For many stores the answer is &lt;em&gt;more than one, for different parts of the catalogue&lt;/em&gt;. The variants of one product line want a rule; the flagship products want per-item attention; the SKU cleanup wants a bulk editor. Using one shape for all three is the real mistake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-three-tool-shapes&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is actually different about this, compared with the tools I already have?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No — the difference is which side supplies the content. In a bulk editor you decide the new value and the tool applies it across the selection. Here the tool composes the value for a specific product and you decide whether it's right. Opposite divisions of labour. A bulk editor with an approval step would still be waiting for you to type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can't a rule engine just write good descriptions too?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It writes consistent ones, and for a homogeneous catalogue consistent is good. What it can't do is produce a different kind of answer for a product that doesn't fit the pattern — by construction it only knows the fields matched. If your catalogue is uniform, that limitation never fires and the rule engine is the better tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We already run an audit tool. Does that mean we picked wrong?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Almost certainly not. An audit answers a question the other three don't even ask. The mistake would be expecting it to close the items it found — that was never its job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does the per-item cost scale on a large catalogue?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Badly. Approval is linear in the number of items. Don't point this shape at work a rule or a bulk edit would handle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if we don't know whether our catalogue is homogeneous?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's question one again, and the answer is an audit — "how uniform is this catalogue" is an empirical question about your data. The answer is usually &lt;em&gt;partly&lt;/em&gt;, which is why allocation matters more than tool choice.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/arvio-three-tool-shapes?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-three-tool-shapes&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-three-tool-shapes_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Not Our Demo Store: What Product Descriptions Look Like on 225 Real Shopify Storefronts</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:13:34 +0000</pubDate>
      <link>https://dev.to/arvio/not-our-demo-store-what-product-descriptions-look-like-on-225-real-shopify-storefronts-2ieo</link>
      <guid>https://dev.to/arvio/not-our-demo-store-what-product-descriptions-look-like-on-225-real-shopify-storefronts-2ieo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/arvio-on-a-real-catalogue?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-on-a-real-catalogue&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We read 8,019 products from 225 live Shopify storefronts that have nothing to do with us. The median product description is 701 characters of plain text.&lt;/p&gt;

&lt;p&gt;Thin descriptions are real, but they are not everywhere. They pile up: of the 205 stores with enough products to measure, 102 had no thin descriptions at all, while 10 had almost nothing else.&lt;/p&gt;

&lt;p&gt;Everything below is one measurement, on one day, of one thing — how long the text is. That is narrow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What we measured&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Storefront addresses we started from&lt;/td&gt;
&lt;td&gt;230&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storefronts that answered&lt;/td&gt;
&lt;td&gt;225&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Products read&lt;/td&gt;
&lt;td&gt;8,019&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Products with an empty description&lt;/td&gt;
&lt;td&gt;389 (4.9%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Products with a description under 200 characters&lt;/td&gt;
&lt;td&gt;1,265 (15.8%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median description length&lt;/td&gt;
&lt;td&gt;701 characters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stores with at least 5 products&lt;/td&gt;
&lt;td&gt;205&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median per-store share of thin descriptions&lt;/td&gt;
&lt;td&gt;2.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quartiles of that per-store share&lt;/td&gt;
&lt;td&gt;0.0% and 18.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stores with zero thin descriptions&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stores where nearly every description is thin&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu3l1u4urxj5400n8igb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu3l1u4urxj5400n8igb9.png" alt="Across 225 public storefronts, the median product description runs 701 characters" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lengths are measured as plain text — HTML tags are stripped before counting, so this is the number of characters a shopper actually reads.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One caveat belongs right here rather than at the bottom: "under 200 characters" means short, not bad. Some of those 1,265 are exactly the right length for what they are selling. Which ones is a judgment we did not make, and a character count cannot.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-on-a-real-catalogue&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where the list came from
&lt;/h2&gt;

&lt;p&gt;The addresses come from the Store Feedback board on the Shopify Community forum, where merchants post their own storefront URL and ask other merchants to look at it.&lt;/p&gt;

&lt;p&gt;That gives the list four properties worth naming:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public.&lt;/strong&gt; The URLs were posted by the store owners, in the open, on a forum anyone can read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducible.&lt;/strong&gt; The board is still there; anyone can pull the same kind of list and run the same check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-selected.&lt;/strong&gt; Every store is on the list because its owner chose to put it there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unrelated to us.&lt;/strong&gt; None of this comes from our customer list. We did not look at who uses our product, and could not have told you either way while collecting it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The method was a single anonymous request per store: &lt;code&gt;GET /products.json?limit=50&lt;/code&gt;, the same public catalogue endpoint any Shopify storefront serves unless it has been locked down. Collection date: 2026-09-05. Of the 230 addresses, 225 answered; we left the rest out rather than guessing.&lt;/p&gt;

&lt;p&gt;Those 230 are what survived a larger list. The board yielded 474 candidate domains over nineteen months, and 244 of them did not answer with a readable catalogue. The largest groups: 118 no longer resolve, 56 return 404, 31 come back with the HTTP status Shopify serves for a frozen unpaid store, and 18 are password-protected or no longer Shopify. Those four account for 223; the remaining 21 are smaller buckets and a handful our records do not classify. Not answering is not proof a store is gone — a locked-down storefront reads the same way from outside as a dead one. Every store below is one that did answer on the day we looked. Stores that failed hardest are the ones most likely to be missing from it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a convenience sample, not a random one.&lt;/strong&gt; A merchant who asks strangers on a forum for feedback skews newer, smaller and more likely to be struggling than one who does not. Every number here should be read as "among stores of that kind," not "among Shopify stores." If you want to know what a mature catalogue looks like, this is the wrong instrument.&lt;/p&gt;

&lt;p&gt;We are also not naming any store, domain, or recognisable product. The point was the shape of the distribution, and the shape does not need anyone's name attached to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The distribution, store by store
&lt;/h2&gt;

&lt;p&gt;Read only the catalogue-wide figure — 15.8% of products under 200 characters — and you would conclude that most stores have a scattering of thin ones. That reading is wrong.&lt;/p&gt;

&lt;p&gt;Take the 205 stores with at least 5 products, so a per-store percentage means something. The median store's share of thin descriptions is 2.0%. The quartiles are 0.0% and 18.1%. And 102 of those 205 stores — about half — have no thin descriptions at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx96bzl3sb9v9qmr81udf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx96bzl3sb9v9qmr81udf.png" alt="Most stores have almost no thin descriptions; a few have almost nothing else" width="799" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The per-store shares do not cluster around the catalogue-wide 15.8%. They pile up at zero, with a long tail stretching to the stores where nearly every description is thin.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At the other end, 10 stores have almost nothing but thin descriptions. Between them they account for 323 thin products — a quarter of the 1,265 we found across all 225 stores, concentrated in ten of them — a small number of stores carrying a disproportionate share of the total.&lt;/p&gt;

&lt;p&gt;So the summary is &lt;strong&gt;concentration, not prevalence&lt;/strong&gt;. This is not "merchants write bad descriptions." It is closer to: most of these storefronts have normal-length descriptions on nearly everything, and a small group has a catalogue that was filled in mechanically — imported, bulk-created, or never revisited — and left that way.&lt;/p&gt;

&lt;p&gt;That distinction matters. A problem spread thinly across every store is a habit problem, fixed by changing how you write. A problem concentrated in a few catalogues is usually an event problem — an import, a migration, a supplier feed — fixed by going back and filling in what the event skipped.&lt;/p&gt;

&lt;p&gt;The empty descriptions are the unambiguous end of this: 389 products, 4.9% of what we read, have no description text at all.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-on-a-real-catalogue&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_listing_mid" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The 50-product ceiling
&lt;/h2&gt;

&lt;p&gt;One request per store, &lt;code&gt;limit=50&lt;/code&gt;, means we saw at most 50 products per storefront. 126 of the 225 stores hit that ceiling: their real catalogues are larger than what we read, and we do not know by how much.&lt;/p&gt;

&lt;p&gt;The obvious worry is that this bends the result. So we split the sample and checked.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The 99 stores that did &lt;strong&gt;not&lt;/strong&gt; hit the ceiling gave us 1,719 products, of which 13.8% had descriptions under 200 characters.&lt;/li&gt;
&lt;li&gt;The 126 stores that &lt;strong&gt;did&lt;/strong&gt; hit the ceiling came in at 16.3%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same direction, close enough in size that truncation is not manufacturing the pattern. Had the truncated stores been dramatically cleaner or dramatically worse than the ones we read in full, the two figures would have pulled apart.&lt;/p&gt;

&lt;p&gt;What this does &lt;strong&gt;not&lt;/strong&gt; show is that larger stores are worse. Hitting the ceiling only tells you a catalogue has more than 50 products — not how many more — and the 16.3% figure is computed on the first 50 products of each of those stores, not on their full catalogues. The only claim here is narrow: cutting each store off at 50 did not send the result somewhere it would not otherwise have gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this data cannot answer
&lt;/h2&gt;

&lt;p&gt;We measured one thing: characters of plain text in a product description. That is a crude instrument, and it is worth being precise about the edges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Length is not quality.&lt;/strong&gt; A long description can be padded, repetitive or wrong. A short one can be exactly right — a single well-chosen sentence about a simple product, for a shopper who already knows what they are buying, is not a defect. When we say 1,265 products are under 200 characters, we are saying they are short. Not that they are bad, and not that they were "filled in but useless." Deciding which short descriptions are fine and which are a gap needs a human who knows the product, and we did not do that here.&lt;/p&gt;

&lt;p&gt;We can show you what "under 200 characters" looks like, though not from this sample — the measurement recorded lengths, not text, and the stores are anonymous. Here is one from our own demo store, a round acacia tray, 62 characters:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Solid acacia, finished by hand. Hand wash and dry immediately.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nothing about that is wrong. It is accurate, it is readable, and for a shopper who already knows what a serving tray is, it may be all they need. It also says nothing about size, what it is for, or why two of them will not match — which is the judgment call the character count cannot make for you.&lt;/p&gt;

&lt;p&gt;Other things people reasonably ask, which this data genuinely cannot tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alt text.&lt;/strong&gt; We read descriptions, not images. Nothing here supports any claim about how many images have alt text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inventory.&lt;/strong&gt; We did not look at stock levels, so nothing here says whether these products are in stock.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Draft products.&lt;/strong&gt; The public endpoint serves published products. Drafts are invisible to this method, so a store could have a pile of unfinished products we never saw.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duplicate descriptions.&lt;/strong&gt; We are not reporting duplicates here, so we quote no duplicate figure at all — not a count, not a percentage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same name, same product.&lt;/strong&gt; Matching titles are not necessarily duplicates; variants, bundles and seasonal re-listings all look like that from the outside.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What this means for your store
&lt;/h2&gt;

&lt;p&gt;The useful move is not to compare yourself to 15.8% — that figure describes a population you are not a member of. Look at the per-store distribution instead: stores tend to land near one of two places, nearly all descriptions of a normal length, or nearly all of them thin.&lt;/p&gt;

&lt;p&gt;So the first question is which shape your own catalogue has. That is answerable in an afternoon: sort your products by description length and look at the bottom of the list. If there are a handful of short ones and you can name why each is short, you are in the 102. If the bottom keeps going, something happened to your catalogue once and nobody went back.&lt;/p&gt;

&lt;p&gt;The second question is the one length cannot answer: of the short descriptions you have, which are missing something a shopper needs? That means opening products and reading them. For a starting point, we collected &lt;a href="https://arvio.a.xyz/blog/product-description-examples-shopify?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_blog3" rel="noopener noreferrer"&gt;examples of product descriptions that do the job&lt;/a&gt; from real storefronts.&lt;/p&gt;

&lt;p&gt;Arvio is an AI Store Operator: it works inside your store, looks at what is there, drafts the change, then stops and shows you the draft before anything is written. For a catalogue with a long tail of short descriptions, the expensive part is not deciding what to say about a wooden tray — it is doing that several hundred times. The part worth keeping slow is approval: every change is shown for review before it lands, which is &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_blog4" rel="noopener noreferrer"&gt;the whole design of how Arvio writes a fix&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" alt="The same check on one product, before and after" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One product, before and after a drafted rewrite. The decision to accept it stays with the merchant.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The 10 stores in the tail of this sample do not have a writing problem. They have a backlog. Those are different problems, and the second is more tractable than it looks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-on-a-real-catalogue&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions people asked about this data
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How did you pick these stores?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We did not pick them; their owners posted them on the Store Feedback board of the Shopify Community forum. That makes the list public and reproducible — anyone can rebuild it from the same board.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the 701-character median include HTML tags?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. We strip the markup out and count the plain text that remains, so the number reflects what a shopper reads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a description under 200 characters a problem?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, and this data cannot tell you which times. A short description on a simple, familiar product can be the right call; one on a product with materials, sizing and care instructions to communicate probably is not. The 1,265 figure is a list of candidates to look at, not a list of defects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why only 50 products per store?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We asked each storefront for 50 products and no more — &lt;code&gt;limit=50&lt;/code&gt; was our choice, not a cap Shopify imposed. 126 stores hit that ceiling, so their real catalogues are bigger than what we read. We checked whether that bent the result: the 99 untruncated stores came in at 13.8% thin, the truncated 126 at 16.3% — same direction, so the ceiling is not creating the pattern. It still means we have not seen those catalogues in full.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run this on my own store?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, and on anyone else's, because the endpoint is public on any storefront that has not restricted it. The harder part is not fetching — it is deciding what counts as thin for your products, a judgement about your catalogue rather than a threshold you can copy from us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why other people's stores rather than your own demo store?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because our demo store is one catalogue we built, and it tells you nothing about how catalogues look in the wild. The trade is a sample that skews newer and smaller.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/arvio-on-a-real-catalogue?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-on-a-real-catalogue&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-on-a-real-catalogue_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Your First Week With Arvio</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:13:23 +0000</pubDate>
      <link>https://dev.to/arvio/your-first-week-with-arvio-29h0</link>
      <guid>https://dev.to/arvio/your-first-week-with-arvio-29h0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/arvio-first-week?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-first-week&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal of your first week is not to change a lot of products. It's to find out whether you agree with what this thing writes.&lt;/p&gt;

&lt;p&gt;It's a calibration exercise: approve a few changes, go look at what landed, build a sense of which edits you wave through and which you send back.&lt;/p&gt;

&lt;p&gt;Every step below ends with something you can check. If the check fails, stop and look — don't keep going on the assumption that it probably worked.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-first-week&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Day 1: walk the whole path once, end to end
&lt;/h2&gt;

&lt;p&gt;Do one thing on day one: take a single product all the way from install to a verified change in Shopify Admin. Four stops, each with a way to tell whether you're actually at it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install, and confirm the app can see your catalog.&lt;/strong&gt; Open Arvio and ask it about a product you know, by name. &lt;em&gt;How you know it worked:&lt;/em&gt; it comes back with that product's real details. If it can't find a product you're certain exists, the connection isn't doing what you think it is — sort that out before approving anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pick one product and ask for one change.&lt;/strong&gt; Choose something where you'd recognize a bad answer immediately, and ask for one specific thing — rewrite the description, say. &lt;em&gt;How you know it worked:&lt;/em&gt; Arvio comes back with a draft of the new text, not a report telling you the old text is short. A list of problems means you asked for an audit, not an edit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read the confirmation card before you press anything.&lt;/strong&gt; This is the step people skip, and the load-bearing one. The card names the scope of this run. On our own demo store it read:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only this product will be updated — all others left untouched.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;How you know it worked:&lt;/em&gt; the scope on the card matches the scope in your head. If you asked for one product and the card describes something wider, reject it — don't shrug and press approve.&lt;/p&gt;

&lt;p&gt;On how long this takes: in the run we recorded, Arvio's own progress line read &lt;code&gt;Plan complete 39s&lt;/code&gt; before the first card appeared, and &lt;code&gt;22s&lt;/code&gt; on the second round. Those are the app's numbers for one product, on our store, reported on screen — not a benchmark, and not the part of day one that actually costs you anything. The time that matters is yours: reading a card properly is a minute or two of attention, and day one is four cards' worth. Budget an hour and you will finish early.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstp9lxhejfh4osvj2ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstp9lxhejfh4osvj2ln.png" alt="The confirmation card, before anyone presses anything" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approve, then go look in Shopify Admin.&lt;/strong&gt; The result card confirms what happened:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✓ Description updated&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and then it hands you the way out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This action can be undone. Let me know if you'd like to revert it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;How you know it worked:&lt;/em&gt; open that product in Shopify Admin yourself. The description field should hold the new text. If the Admin still shows the old text, the change did not land — no matter what the result card said. The Admin is the record; the card is a claim about the record.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff80pulrpofmfkgrixemh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff80pulrpofmfkgrixemh.png" alt="The result card, with the undo line and the Admin link" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the one product we measured, "it worked" looked like this in the Admin: the old description was 62 characters, the new one roughly 361 to 364, depending on whether you count the HTML tags. Read that as a single before-and-after we happened to record, not as a length you should expect — one product on one store tells you nothing about the average. The number itself doesn't matter to you. What matters is that you can take that measurement yourself, before and after, without asking us.&lt;/p&gt;

&lt;p&gt;That's day one: one product, four checks, none of which required trusting the copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 2–3: widen to a small batch, and start forming opinions
&lt;/h2&gt;

&lt;p&gt;Days two and three aren't about proving the path works — you did that. They're about what you think of the writing. Widen to a handful of products, not the whole catalog: enough to see several drafts side by side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask for the same kind of change across a few products at once.&lt;/strong&gt; Holding the operation constant is what makes the differences between drafts visible. &lt;em&gt;How you know it worked:&lt;/em&gt; the confirmation card names a wider scope than on day one, and that scope matches the set you asked for. If it names one product while you asked for several, stop — better to find that out from the card than from the Admin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approve them one at a time, and reject at least one on purpose.&lt;/strong&gt; Approval is per change, not per pile — that design is the whole subject of &lt;a href="https://arvio.a.xyz/blog/arvio-approval-workflow?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_blog2" rel="noopener noreferrer"&gt;how approval actually works in Arvio&lt;/a&gt;. Undo has the same grain: one change, one decision, either before it lands or after. Rejecting is the cheap version and reverting is the late one, and you will practise the second half at the end of the week. Find a draft you genuinely don't like and send it back. &lt;em&gt;How you know it worked:&lt;/em&gt; open the rejected product in Shopify Admin. Its old text should still be there while the approved ones show new text. A rejection that wrote anyway is the most important failure to catch, and this is how you catch it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write down, in one line each, why you approved and why you rejected.&lt;/strong&gt; &lt;em&gt;Approved — kept the material and the dimensions; rejected — invented a care instruction we never said.&lt;/em&gt; You're building a rubric, and you won't remember these reasons by Friday.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How you know it worked:&lt;/em&gt; you can read your own notes back and predict the next verdict before opening the draft. If your reasons come out as "felt fine" and "felt off," you don't have a rubric yet — stay at this size longer.&lt;/p&gt;

&lt;p&gt;By the end of day three the useful output isn't the number of products changed. It's the list: a few things you'll always approve, a few you'll always reject.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-first-week&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_listing_mid" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  End of week one: go back and look at what you approved
&lt;/h2&gt;

&lt;p&gt;Go back through everything you approved and ask which ones you'd take back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Re-read your approvals cold.&lt;/strong&gt; Open them in Shopify Admin a few days later, without the draft next to them. Reading a change the way a customer lands on it is a different experience from reading it in a queue. &lt;em&gt;How you know it worked:&lt;/em&gt; you find at least one you want to change. A perfect week usually means you read it the same way twice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revert the ones you want back.&lt;/strong&gt; Using the undo path once during week one is worth more than reading about it. &lt;em&gt;How you know it worked:&lt;/em&gt; open the reverted product in Shopify Admin and confirm the old text is back in the field. Don't take the confirmation message as the answer — go look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" alt="The same check on one product, before and after" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compare the two ends of the week.&lt;/strong&gt; Export your products at the start of the week and again at the end, then diff them. &lt;em&gt;How you know it worked:&lt;/em&gt; the products that differ are exactly the ones you approved. A product that changed without your approval is a real problem, and you want to find it now rather than in month three across the whole catalog. It's the same self-check we describe in &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_blog4" rel="noopener noreferrer"&gt;what it actually looks like when Arvio writes the fix&lt;/a&gt;, and the only one here that needs nothing from us.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to slow down
&lt;/h2&gt;

&lt;p&gt;Two signals mean stop widening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The changes start repeating.&lt;/strong&gt; If the drafts are variations on a shape you've approved many times over, widening adds volume rather than information. Move to a different kind of change, or stay at this size. &lt;em&gt;How you know you're here:&lt;/em&gt; you can predict the draft from the product name before opening it, and you're right most of the time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You've stopped editing what it writes.&lt;/strong&gt; If you've approved three in a row without changing a word, there are two explanations — the drafts got good, or you stopped reading — and they feel identical from the inside. A queue you approve without reading is worse than no queue: it produces a record that looks like review.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How you know you're here:&lt;/em&gt; pick one of your last three approvals at random and open it in Shopify Admin. If you're reading that text for the first time right now, you were rubber-stamping. Drop back to a smaller batch and start editing drafts again.&lt;/p&gt;

&lt;p&gt;There's no penalty for staying small. The nightly pass doesn't expire, and a backlog of unreviewed drafts costs nothing but a longer queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you should uninstall us
&lt;/h2&gt;

&lt;p&gt;The last line of our own App Store description says this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your catalog is small and rarely changes, you don't need us.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We mean it, and the first week is when you should decide.&lt;/p&gt;

&lt;p&gt;If you run a few dozen products and touch them yourself every month or two, you already know your catalog better than a nightly pass will tell you. You'd spot a thin description on sight, and fixing it takes about as long as reading a confirmation card. Installing us puts a review queue in front of a job that didn't have one.&lt;/p&gt;

&lt;p&gt;Two other cases, in the same spirit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your edits are mechanical and identical.&lt;/strong&gt; If what you need is one operation applied uniformly — append a phrase to every title in a collection, shift a set of prices by a fixed amount — you don't need something that drafts each change and stops to ask. A tool built for uniform operations across many rows will do that faster. If you already know what every product needs and it's the same thing, the deciding part is dead weight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You don't intend to review anything.&lt;/strong&gt; The stop-and-wait design is the product. If you were hoping to install something, grant it access, and never look at the output, this shape of tool is a tax rather than a help: you'd approve without reading, which gets you unreviewed edits plus a queue. Budget the reading time or pick something else.&lt;/p&gt;

&lt;p&gt;If any of those three is you, uninstalling in week one is the correct decision and costs you an evening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-first-week&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How many products should I start with?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One, on the first day. Day one proves the path works end to end, and one product proves that as well as fifty do while being much easier to check. Widen once you've seen a change land in Shopify Admin with your own eyes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I approve something and then change my mind?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The result card tells you the change can be undone, and undo is per change rather than per batch — reverting one edit doesn't drag the others back with it. After you revert, open the product in Shopify Admin and confirm the old text is in the field. Treat the Admin as the answer, not the confirmation message.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I have to review every change forever?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the design, and we'd rather say so than imply it fades once you're comfortable. Experience changes your speed, not whether the step exists. If review is something you want to eliminate rather than get faster at, this isn't the right shape of tool for your store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if the drafts are wrong?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reject them and write down why. A rejected draft costs you the time it took to read — nothing lands in your store. The pattern is what matters: if the same kind of error recurs, that's a fair basis for deciding whether to keep the app, and better learned in week one than in month three.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I limit what it touches?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You set the scope each time, and the confirmation card prints it back at you before anything is written. The check is simple: the scope on the card should match the scope in your head. If it doesn't, reject — that mismatch is the card doing its job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing changed in Shopify Admin after I approved. What now?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Trust the Admin over the card. Reload the product page first, in case you're looking at a stale view. If the old text is genuinely still there, the change did not land — tell us rather than approving more changes on the assumption that the first one worked. Go by what the Admin shows.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/arvio-first-week?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-first-week&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-first-week_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What Arvio Won't Touch</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:12:21 +0000</pubDate>
      <link>https://dev.to/arvio/what-arvio-wont-touch-4kp5</link>
      <guid>https://dev.to/arvio/what-arvio-wont-touch-4kp5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/arvio-what-it-wont-touch?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-what-it-wont-touch&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Giving an AI write access to your product catalog is not a feeling you talk yourself into. It is a question about mechanics: what does it say it's going to do before it does it, and can you put things back afterward?&lt;/p&gt;

&lt;p&gt;Three things carry the weight. Before any write, a confirmation card names the scope of that specific run. After the write, a result card restates what changed and tells you it can be undone. And every change lands in Shopify Admin, where you can look at it without asking us anything.&lt;/p&gt;

&lt;p&gt;That's the whole answer, and it is worth being exact about its shape. The limits below are per-run and mechanical — the scope of a change is named before it happens, and it is reversible after — rather than a standing list of operations Arvio will never perform. If you came here for that list, the next section is the honest version of why there isn't one. The rest of this piece is the part most vendor pages skip: what we do &lt;strong&gt;not&lt;/strong&gt; have, and how to verify the rest for yourself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-what-it-wont-touch&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  First, what we don't have
&lt;/h2&gt;

&lt;p&gt;We do not publish a formal document that lists, operation by operation, the things Arvio will never do. No signed schedule of forbidden actions, no permanent rule you could hold us to in writing.&lt;/p&gt;

&lt;p&gt;We could write one. We haven't. A list like that is only as good as the enforcement behind it, and the enforcement we have today is not a document — it's the two cards described below, plus Shopify's own record of every change.&lt;/p&gt;

&lt;p&gt;So read the rest of this as a description of how the product behaves in the runs we've recorded, not as a promise about every run forever. Those are different kinds of statements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before anything is written, the card names the scope
&lt;/h2&gt;

&lt;p&gt;Arvio doesn't ask for permission in the abstract. It asks about one specific pending change, and it says out loud how far that change reaches.&lt;/p&gt;

&lt;p&gt;In the run we recorded on our own demo store, the confirmation card carried this line:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only this product will be updated — all others left untouched.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next to the card's heading sat one more word in parentheses: &lt;strong&gt;(reversible)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstp9lxhejfh4osvj2ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstp9lxhejfh4osvj2ln.png" alt="The confirmation card names the scope before anything is written" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That sentence is a receipt for &lt;strong&gt;that run's scope&lt;/strong&gt;, not a statement about what Arvio is capable of. The prompt driving that particular task said, in so many words, to leave every other product untouched — and the card was confirming it had understood the boundary it was given. Read it as "here is the scope of the thing I'm about to do," not as "I don't touch other products." Arvio absolutely can work across more than one product. That's largely the point of it.&lt;/p&gt;

&lt;p&gt;The App Store listing says the same thing from the other direction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One product, a batch you pick, or all of them — you choose the scope&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the actual boundary: not a rule we wrote down, but a decision you make each time, printed back at you before the write happens. If you want to see what a finished change looks like when it lands, we walked through one in &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_blog2" rel="noopener noreferrer"&gt;what it actually looks like when Arvio writes the fix&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The undo path
&lt;/h2&gt;

&lt;p&gt;The second thing holding up write access is that the writes come apart again.&lt;/p&gt;

&lt;p&gt;From the listing's feature list:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Approve or reject each change one by one; undo any edit in one click&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And from the product description on the same listing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You approve or reject them one by one, and any edit undoes in one click.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a change goes through, the result card repeats the scope and then adds the exit:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All other products left untouched.&lt;/p&gt;

&lt;p&gt;This action can be undone. Let me know if you'd like to revert it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff80pulrpofmfkgrixemh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff80pulrpofmfkgrixemh.png" alt="The result card restates what changed, with an undo line and a link into Admin" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Approval is per change, not per batch. You are not handed a pile of edits and asked to bless the pile. Each one stands or falls on its own, and a reverted edit doesn't drag the others back with it.&lt;/p&gt;

&lt;p&gt;A rule tells you what someone intends. An undo tells you what you can do when the intent and the outcome part ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check it yourself
&lt;/h2&gt;

&lt;p&gt;You don't have to take the cards at their word.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow the Admin link.&lt;/strong&gt; Every result card ends with an exit into Shopify:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;View in Shopify Admin →&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That drops you on the product in your own admin, where the change is just a change — visible, editable, and revertible by you, with or without us. Shopify's own edit history is the record here, not ours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with one product.&lt;/strong&gt; The scope control exists so you can use it. Point Arvio at a single product you know well, read the confirmation card, let it write, then compare. One product tells you most of what a hundred would.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compare the catalog before and after.&lt;/strong&gt; On our demo store we took the whole catalog on either side of a run. Sixty-eight products going in, sixty-eight coming out — nothing created, nothing deleted. One of them was different: an Acacia Round Tray, whose description went from 62 characters to 364. That is one run, on a store we own, from a prompt we wrote ourselves — it demonstrates that the check works and what a clean result looks like, and it is not evidence about how Arvio behaves on catalogues we have never seen. The point of putting it here is that you can run the same comparison on yours, where the result is about your store rather than ours.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpvvfnatu6s8hwx7zq2z.png" alt="Sixty-eight products before the run, sixty-eight after, one of them different" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One product changed out of sixty-eight, because that run's scope was one product. That's the shape of evidence you can generate yourself on any store, with no cooperation from us: export before, export after, diff the two.&lt;/p&gt;

&lt;p&gt;We prefer this to a policy document for a reason that has nothing to do with modesty. A policy document is a claim. A catalog diff is a measurement, and you can take it yourself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-what-it-wont-touch&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_listing_mid" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  It can be wrong, and it says so
&lt;/h2&gt;

&lt;p&gt;There's a line sitting at the bottom of the interface the whole time you're using it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Arvio is AI and can make mistakes — please verify before acting&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the operating assumption the rest of the design is built on. The per-change approval flow, the undo, the Admin link — those only make sense if you assume some changes will be wrong and you need a cheap way to catch and reverse them. A product that believed its own output was always right wouldn't need any of that machinery.&lt;/p&gt;

&lt;p&gt;The sequencing follows from the same assumption. Arvio writes first and asks second, which sounds backwards until you've reviewed a report. From the listing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You shouldn't have to know what's broken. Arvio reads every product nightly and writes each fix.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A report hands the work back to you. A written draft hands you a decision. We made that case at more length in &lt;a href="https://arvio.a.xyz/blog/why-fix-not-report?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_blog4" rel="noopener noreferrer"&gt;why we write the fix instead of reporting the problem&lt;/a&gt; — and the reason that trade is acceptable at all is everything above: the draft is scoped, it's approved one at a time, and it comes apart in one click.&lt;/p&gt;

&lt;h2&gt;
  
  
  We'll say it: you might not need us
&lt;/h2&gt;

&lt;p&gt;The last line of our own App Store description says this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your catalog is small and rarely changes, you don't need us.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We left it there on purpose.&lt;/p&gt;

&lt;p&gt;If you run a small catalog and you touch it yourself every few weeks, you already have what Arvio provides. You know your catalog. You'd spot the gap faster than any nightly pass would, and you'd fix it in the time it takes to read a confirmation card. Installing us would add a review queue to a job that didn't have one.&lt;/p&gt;

&lt;p&gt;The math changes at scale and at churn. A catalog you inherited, or one that turns over faster than you can keep up with, and the bottleneck stops being &lt;em&gt;knowing what's wrong&lt;/em&gt; and becomes &lt;em&gt;someone actually doing them&lt;/em&gt;. That's the gap Arvio fills. If that's not your gap, we'd rather you found that out from us than from a month of paying for a queue you don't read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-what-it-wont-touch&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; It writes the change, then waits for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The card says "all others left untouched." Does that mean Arvio never touches other products?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No — and this is the single most important clarification in this article. That line is the scope receipt for that particular run, which had been asked to work on one product and leave the rest alone. It confirms the boundary Arvio was given, not a standing limit on what it does. Arvio works across a batch you pick or the whole catalog when that's the scope you set. Read each card as a statement about that run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a document listing the operations Arvio will never perform?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. We don't publish one. What we have instead is per-run scope stated on the card before the write, per-change approval, one-click undo, and Shopify Admin as the independent record. If you need a written boundary for a procurement process, ask us rather than assuming the page you're reading is one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if a change is wrong?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You reject it at the approval step, or undo it afterward. The listing puts it as: any edit undoes in one click. The result card says the same: &lt;em&gt;This action can be undone.&lt;/em&gt; And the interface carries a standing reminder that Arvio is AI and can make mistakes and you should verify before acting — the review step exists because that's true.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I try it on one product before letting it near the catalog?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, and we'd suggest it. The listing describes the scope choice as one product, a batch you pick, or all of them. Start at one, read the confirmation card, approve, then look at the result in Admin. You'll learn more from that than from any description we could write.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I independently verify nothing else changed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Export your catalog before a run and after it, and diff them. On our demo store that comparison showed sixty-eight products before and sixty-eight after, with one product different — the Acacia Round Tray, description 62 characters to 364. Nothing created, nothing removed. You can run that check on your own store without us being involved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Arvio need access to my theme or storefront code?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvio is an AI Store Operator working on your product catalog — it reads your products and writes changes to them, which you approve one by one. We are not going to make a permanent claim here about every surface in your store; what we'll tell you is that the permissions Shopify grants an app are visible to you in Admin before you install, and you should read that screen rather than take a blog post's word for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I'd rather it just told me what's wrong?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then you want a report, and there are plenty of those. Our position is that a list of problems moves the work back to you, which is the same place it was stuck. Arvio writes the change and then waits, so the thing you're deciding on is a finished draft rather than a task.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/arvio-what-it-wont-touch?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-what-it-wont-touch&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-what-it-wont-touch_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What You're Actually Approving When You Press That Button</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:12:08 +0000</pubDate>
      <link>https://dev.to/arvio/what-youre-actually-approving-when-you-press-that-button-4lfp</link>
      <guid>https://dev.to/arvio/what-youre-actually-approving-when-you-press-that-button-4lfp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/arvio-approval-workflow?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-approval-workflow&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Arvio writes the change first, then stops and shows it to you. Nothing reaches your store until you press one button.&lt;/p&gt;

&lt;p&gt;So the interesting question isn't "does it work." It's: &lt;strong&gt;what exactly is on the screen in the moment before you press?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the whole card, transcribed from a real run on our own demo store:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What's on the card&lt;/th&gt;
&lt;th&gt;The text&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Title&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Confirm Description Rewrite — Acacia Round Tray&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reversibility marker&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;(reversible)&lt;/code&gt; — in green&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Which product&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Acacia Round Tray&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope line&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Only this product will be updated — all others left untouched.&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current Description&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Solid acacia, finished by hand. Hand wash and dry immediately.&lt;/code&gt; — struck through&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New Description&lt;/td&gt;
&lt;td&gt;An editable text box, with a resize handle in the corner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The button&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Confirm Update&lt;/code&gt; — black, not yet pressed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each of those is answering a question you'd otherwise have to go and ask.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-approval-workflow&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What that card is actually telling you
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fole8vd99mct2u0t1z3d8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fole8vd99mct2u0t1z3d8.png" alt="The confirmation card, before anyone presses anything" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is the state we spend the most time looking at: the change is fully written, and none of it has happened yet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The title names the operation and the object.&lt;/strong&gt; Not "Arvio wants to make changes" — &lt;code&gt;Confirm Description Rewrite — Acacia Round Tray&lt;/code&gt;. You know what kind of edit and to which product before reading anything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;(reversible)&lt;/code&gt; sits right under it, in green.&lt;/strong&gt; This is a property of the operation, shown up front rather than discovered afterward. It's telling you the cost of being wrong here is low — which is a different decision than one where the cost of being wrong is high.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The scope line is the one I'd read twice.&lt;/strong&gt; It says: &lt;code&gt;Only this product will be updated — all others left untouched.&lt;/code&gt; This is worth being precise about, because it's easy to over-read. The prompt for this run was &lt;em&gt;"Rewrite the product description for one product only: Acacia Round Tray. Leave every other product untouched."&lt;/em&gt; So that line is Arvio confirming back the scope of &lt;strong&gt;this&lt;/strong&gt; task — it's a receipt for what you asked, not a standing promise about how the product behaves in general. If you ask for a change across a category, the scope line will say something else. Read it as "here's what I understood you to want," and check that it matches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The current description is shown with a strikethrough.&lt;/strong&gt; You don't have to open another tab to remember what's there now. The thing being replaced is on screen next to the thing replacing it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The new description is in an editable box, not a block of display text.&lt;/strong&gt; More on this below — it's the part that changes what "approve" even means.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And &lt;code&gt;Confirm Update&lt;/code&gt; is a button that hasn't been pressed.&lt;/strong&gt; That's the state the whole system is designed to park in.&lt;/p&gt;

&lt;p&gt;Around the card, the same screen shows a few things that aren't the decision but frame it: &lt;code&gt;Plan complete 39s ▼&lt;/code&gt; (you can expand what it did), &lt;code&gt;2/6 connected&lt;/code&gt;, &lt;code&gt;Not subscribed&lt;/code&gt;, a &lt;code&gt;Was this answer helpful? / Useful / Needs work&lt;/code&gt; prompt, and a standing line at the bottom: &lt;code&gt;Arvio is AI and can make mistakes — please verify before acting&lt;/code&gt;. That last one isn't decoration. The card exists because of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  We ran it once. Here's what happened to the catalog.
&lt;/h2&gt;

&lt;p&gt;Card text is one thing; what actually landed in the store is another. So we diffed the catalog before and after.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffppwr8kpkgpkq2d2380e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffppwr8kpkgpkq2d2380e.png" alt="Before and after: 62 characters became 364" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The description on that one product went from 62 characters to 364 — roughly six times longer — and the other 67 products came out of the run byte-identical.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;68 products before, 68 products after.&lt;/strong&gt; Nothing created, nothing deleted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 product changed.&lt;/strong&gt; The one named on the card.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;62 → 364 characters&lt;/strong&gt; on that product's description.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The old text was &lt;code&gt;Solid acacia, finished by hand. Hand wash and dry immediately.&lt;/code&gt; — accurate, and about as much help to a shopper as a shipping label. The new text describes the grain, suggests what you'd put on it, and keeps the care instruction at the end.&lt;/p&gt;

&lt;p&gt;That's one product, one prompt, one store — ours. It shows the shape of the edit, and that the diff matched what the card said it would be. What happens on a large catalog with several people editing at once is a different question, and we haven't measured it.&lt;/p&gt;

&lt;h2&gt;
  
  
  You can rewrite it before you approve it
&lt;/h2&gt;

&lt;p&gt;The New Description field is a text box. There's a resize handle on it. That single detail splits "approve" into two different actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Approve what it wrote.&lt;/strong&gt; You read it, it's good, you press.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approve your edit of what it wrote.&lt;/strong&gt; You change a phrase, fix a product detail it couldn't know, cut a sentence — then press.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The second one is the case that matters most in practice, and it's the case a pure yes/no gate throws away. If the only options are accept and reject, then a draft that is mostly right is a rejection, and you're back to writing it yourself from a blank field. With an editable box, a draft that is mostly right is a small edit.&lt;/p&gt;

&lt;p&gt;This matters for exactly the things a model can't get from your catalog data. Whether the acacia is FSC-certified. Whether you've been calling it a "serving tray" in your ads for two years. Whether that care instruction is legally required wording in your market. Arvio drafts the structure and the language; you supply the facts only you have.&lt;/p&gt;

&lt;p&gt;Whatever's in the box when you press is what gets written. That's the whole contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  What this looks like when it's not one product
&lt;/h3&gt;

&lt;p&gt;The run above is deliberately the smallest possible case: one product, so the diff is easy to check. If you came here with four hundred products, the question you actually have is what this card looks like multiplied.&lt;/p&gt;

&lt;p&gt;Two things we can point at, and one we can't. Our App Store listing describes the scope choice as &lt;code&gt;One product, a batch you pick, or all of them — you choose the scope&lt;/code&gt;, and the approval step as &lt;code&gt;Approve or reject each change one by one; undo any edit in one click&lt;/code&gt;. That's the documented behaviour.&lt;/p&gt;

&lt;p&gt;There is one recorded run on a batch rather than a single product, and it is public: a price change applied across a product grid, with the confirmation card read line by line before the press.&lt;/p&gt;

&lt;p&gt;What we haven't published is a measured run at that size — how the cards are paced, what a hundred of them in sequence feels like, where the review stops being careful. We've written about the attention problem further down, because it's the part we'd want to know about if we were you. But we're not going to describe a four-hundred-product session we haven't recorded and shown you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-approval-workflow&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_listing_mid" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The card comes before the write
&lt;/h2&gt;

&lt;p&gt;Here's what we measured: the card appeared, we pressed the button, and the catalog changed. The diff is the result of that press — 68 products in, 68 out, one of them different.&lt;/p&gt;

&lt;p&gt;So the card sits &lt;em&gt;before&lt;/em&gt; the write, not after it. Up to that press the change is a proposal held in the conversation: the draft exists, the store doesn't know about it. Nothing on the card is an edit that already landed and is waiting to be un-landed.&lt;/p&gt;

&lt;p&gt;That last sentence is read off the order of events, not off a recording of someone declining — our capture of this run goes prompt → card → press → done, and we don't have footage of a rejection to show you. If you want certainty for your own store, it's a cheap thing to check on one product: note its current description, walk up to a card, close it without pressing, and look at the product again.&lt;/p&gt;

&lt;p&gt;The timeline of our run shows one more thing. (Not a speed claim — that capture was sped up, so the durations in it would be misleading.) It's this: &lt;strong&gt;once the card is on screen, it stays there.&lt;/strong&gt; The gap between the card appearing and the button being pressed is however long the person took. Nothing times out and decides for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you should actually reject
&lt;/h2&gt;

&lt;p&gt;The card is only worth having if you sometimes say no. Concretely, these are the moments to stop:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The scope line doesn't match what you asked for.&lt;/strong&gt; You asked for one product; the card describes a category. That's not a bad rewrite, it's a misread instruction, and editing the text box won't fix it. Reject and re-prompt with tighter wording.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It asserts a fact you can't verify.&lt;/strong&gt; Material, origin, dimensions, certification, compatibility. Our new description says "solid acacia wood" — true, because the old description said so and it's our store. If a draft introduces a specification that wasn't already in your catalog, treat it as a claim needing a source, not as copy. This is the failure mode I'd watch for most closely: fluent, plausible, and wrong is harder to catch than obviously broken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It quietly drops something load-bearing.&lt;/strong&gt; In our run the care instruction survived — &lt;code&gt;hand wash and dry immediately&lt;/code&gt; shows up in both versions. Compression tends to delete qualifiers first, and qualifiers are often the legally or practically important part. Before you press, check that every constraint in the old text is still somewhere in the new one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's off-voice in a way that's easier to re-prompt than to hand-edit.&lt;/strong&gt; If you'd have to rewrite more than half the box, don't. Reject, adjust the instruction, and let it draft again. Editing is for fixing a draft, not for salvaging one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You're not in a position to read it properly.&lt;/strong&gt; The card waits. That's the feature.&lt;/p&gt;

&lt;p&gt;None of these require you to know anything about the model. They require you to know your products — which you do, and which is exactly why the gate is where it is. We wrote separately about &lt;a href="https://arvio.a.xyz/blog/why-fix-not-report?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_blog3" rel="noopener noreferrer"&gt;why Arvio hands you a finished change instead of a list of problems to go fix yourself&lt;/a&gt;; this is the other half of that argument. A report puts the work on you. A finished change with no gate puts the risk on you. The card is the position where you carry neither.&lt;/p&gt;

&lt;h2&gt;
  
  
  After you press
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F653o3u1yccevabmyevsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F653o3u1yccevabmyevsa.png" alt="The result card, with the undo line and the Admin link" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The result card restates both versions in full, so the record of what changed lives in the conversation and not only in your store.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The confirmation resolves into a result card:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Description updated — Acacia Round Tray
All other products left untouched.
✓ Description updated
Old description: Solid acacia, finished by hand. Hand wash and dry immediately.
New description: Crafted from solid acacia wood and finished by hand, this round tray
brings warm, natural grain to any table. …
💡 This action can be undone. Let me know if you'd like to revert it.
Result Verification / View in Shopify Admin →
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things here do real work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Both versions, in full.&lt;/strong&gt; Not "updated ✓" — the old text and the new text, one above the other, after the fact. If you approve a batch of these and something looks wrong tomorrow, the old string is still sitting in your conversation history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;This action can be undone.&lt;/code&gt;&lt;/strong&gt; The &lt;code&gt;(reversible)&lt;/code&gt; marker from before the press, restated as a fact after it. And the mechanism is a sentence, not a hunt through settings: you tell it to revert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;View in Shopify Admin →&lt;/code&gt;.&lt;/strong&gt; The link out to the source of truth. We use it constantly, and I'd suggest you do too for the first several changes — not because we expect a mismatch, but because "verify before acting" is printed on the screen for a reason, and the fastest way to build a calibrated sense of when you can skim a card is to check a few of them all the way through.&lt;/p&gt;

&lt;p&gt;If you want to see what the drafts themselves look like across more than one kind of edit, that's the subject of &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_blog4" rel="noopener noreferrer"&gt;our walkthrough of what a finished Arvio change actually reads like&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this gets uncomfortable
&lt;/h2&gt;

&lt;p&gt;The honest tension in this design: a gate you press a hundred times stops being a gate.&lt;/p&gt;

&lt;p&gt;Card ten gets read carefully. Card ninety, at the end of a Tuesday, gets a glance and a press. We know this, and we haven't solved it. The design choices above — showing the old text struck through, restating both versions afterward, putting the Admin link in the result — are partly hedges against the moment you approve on autopilot. They don't eliminate it.&lt;/p&gt;

&lt;p&gt;So front-load your attention. Read the first ten cards all the way through, click into Admin on a few, and build a sense of where this thing is reliably good and where it needs you. Then you'll know which cards you can move through quickly and which ones deserve the full read — and that judgment is worth more than any promise we could put in a marketing page.&lt;/p&gt;

&lt;p&gt;The other limit worth naming: what we've shown you here is one operation type on one product. Description rewrites are a good case for this pattern because they're reversible, self-contained, and easy to eyeball. Not every operation has those properties. Price changes touch what customers pay; deletions don't have an obvious "before" to restore from memory. The test we'd apply before approving anything quickly is whether you could describe the undo out loud — if you can't say how you'd put it back, that's a card to read all the way through, whatever the marker says. We'd rather give you that test than generalize from the one operation we've measured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-approval-workflow&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; It drafts the change, then stops and shows you the card.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does Arvio write to my store before I approve?&lt;/strong&gt;&lt;br&gt;
The card appears before the write, and the diff we measured is the result of pressing the button. We only captured the approval path, so I'll describe what the structure implies rather than claim we filmed the alternative: at card time the change is a proposal, not something already applied. If you want certainty, test it on one product and check the result in Admin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I change the text before approving?&lt;/strong&gt;&lt;br&gt;
Yes. The New Description field is an editable text box with a resize handle. Whatever is in it when you press &lt;code&gt;Confirm Update&lt;/code&gt; is what gets written — so "approve" and "approve my edited version" are the same button.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does &lt;code&gt;(reversible)&lt;/code&gt; mean?&lt;/strong&gt;&lt;br&gt;
It's a marker on the card, shown before you press, and it's restated on the result card as &lt;code&gt;This action can be undone.&lt;/code&gt; You revert by telling Arvio to revert it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does "all others left untouched" mean it will never modify other products?&lt;/strong&gt;&lt;br&gt;
No, and this distinction matters. That line confirms the scope of the task you asked for — in our run the prompt explicitly said "leave every other product untouched," and the catalog diff backs that up: 68 products before, 68 after, exactly 1 changed. If you ask for a broader change, the scope line will describe a broader change. Read it every time; it's a receipt for one task, not a permanent rule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long does the card wait?&lt;/strong&gt;&lt;br&gt;
As long as you do. In our run the gap between the card appearing and the press was however long the person took to read it — nothing expires or decides on your behalf. (I'm deliberately not quoting durations from that capture: the footage is sped up and any number would read as a speed claim we haven't earned.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does a description actually change?&lt;/strong&gt;&lt;br&gt;
In the run we diffed, one product's description went from 62 characters to 364 — roughly six times longer. That's one product on our own demo store, and I wouldn't extrapolate an average from a sample of one. The number is here because it's what we measured, not because it's a benchmark.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/arvio-approval-workflow?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-approval-workflow&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-approval-workflow_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What It Looks Like When the Fix Is Already Written</title>
      <dc:creator>Arvio</dc:creator>
      <pubDate>Mon, 21 Sep 2026 06:09:50 +0000</pubDate>
      <link>https://dev.to/arvio/what-it-looks-like-when-the-fix-is-already-written-2m9g</link>
      <guid>https://dev.to/arvio/what-it-looks-like-when-the-fix-is-already-written-2m9g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a repost. Originally published on the Arvio blog: &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_origin_top" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-writes-the-fix&lt;/a&gt;. The canonical URL points back there.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Other tools tell you what's wrong. This one has already written the fix — you just approve it.&lt;/strong&gt; This post is one recorded run on our own demo store, screen by screen, so you can see what that actually means before installing anything.&lt;/li&gt;
&lt;li&gt;The product we asked about had a &lt;strong&gt;62-character&lt;/strong&gt; description: &lt;code&gt;Solid acacia, finished by hand. Hand wash and dry immediately.&lt;/code&gt; What came back was a &lt;strong&gt;364-character&lt;/strong&gt; replacement, already drafted, sitting in an editable box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing was written until a button was pressed.&lt;/strong&gt; The confirmation card says, in those words: &lt;code&gt;Only this product will be updated — all others left untouched.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;After it ran, the result card carried &lt;code&gt;✓ Description updated&lt;/code&gt; and the line &lt;code&gt;This action can be undone. Let me know if you'd like to revert it.&lt;/code&gt; — we exercised the forward path only, so treat the undo as what the product offers, not as something this recording demonstrates.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The gap isn't knowing which products are thin. It's that fixing them is typing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See it on your own catalogue&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvio is an AI store operator: it reads your live catalogue, drafts the change, and shows it to you before anything is written.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-writes-the-fix&amp;amp;source_section=blog_top&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_listing_top" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why a walkthrough instead of a feature list
&lt;/h2&gt;

&lt;p&gt;Most descriptions of this kind of tool stop at the noun. "It rewrites product descriptions" is true of a great many things, including a text box and some patience. What it doesn't tell you is the part that decides whether you'd actually use it: what happens between asking and the change landing, and how much of that you control.&lt;/p&gt;

&lt;p&gt;So this is a recording rather than a claim. One prompt, one product, on our own demo store. Everything quoted below is text that was on screen.&lt;/p&gt;

&lt;p&gt;The instruction we typed was deliberately narrow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rewrite the product description for one product only: Acacia Round Tray. Leave every other product untouched.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What was there before
&lt;/h2&gt;

&lt;p&gt;The product had a description. That's worth saying, because the interesting case isn't the empty field — it's the one that's technically filled and does no work:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Solid acacia, finished by hand. Hand wash and dry immediately.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sixty-two characters. It's accurate. It tells a shopper the material and how to wash it, and nothing about why the thing is worth buying — &lt;a href="https://arvio.a.xyz/blog/product-description-examples-shopify?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_blog2" rel="noopener noreferrer"&gt;what a description that does the work looks like&lt;/a&gt; is its own subject. Nothing in any admin flags this, because from the system's point of view the field is populated and the product is fine.&lt;/p&gt;

&lt;p&gt;This is the category of problem that survives every audit you run. A checker asks "is the description empty?" and gets a no.&lt;/p&gt;

&lt;h2&gt;
  
  
  What came back: a draft, not a diagnosis
&lt;/h2&gt;

&lt;p&gt;Here is the part that's difficult to convey without a picture. The response was not a report saying the description was thin, and not a suggestion that it be improved. It was the replacement text, already written, in a box you can edit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5phzze2hqmiatnx1pccb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5phzze2hqmiatnx1pccb.png" alt="The old description struck through, the rewritten 364-character version already drafted in an editable box, and the Confirm Update button that hasn't been pressed yet." width="798" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The old line is struck through. Below it, under &lt;code&gt;New Description (editable)&lt;/code&gt;, sits the full replacement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Crafted from solid acacia wood and finished by hand, this round tray brings warm, natural grain to any table. Its generous surface is perfect for serving drinks, breakfast in bed, or keeping everyday essentials tidy. Because every piece of acacia has its own unique grain, no two trays are exactly alike. To keep it looking its best, hand wash and dry immediately.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's 364 characters of plain text against the original 62 — the lengths our catalogue diff recorded for the stored field before and after this run.&lt;/p&gt;

&lt;p&gt;Two things about that box are worth more than the word count. It is &lt;strong&gt;editable&lt;/strong&gt; — the draft is a starting point, not a verdict. And the button next to it had not been pressed. At this moment in the recording, nothing in the store had changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The confirmation card is the actual feature
&lt;/h2&gt;

&lt;p&gt;What makes write access to your catalogue acceptable isn't the quality of the drafting. It's that you can see precisely what it is about to do, in narrow enough terms that you could refuse.&lt;/p&gt;

&lt;p&gt;The card states its scope in a sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only this product will be updated — all others left untouched.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It names the product, &lt;code&gt;Acacia Round Tray&lt;/code&gt;, shows the current description and the proposed one side by side, and labels itself &lt;code&gt;(reversible)&lt;/code&gt;. The button reads &lt;code&gt;Confirm Update&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the inversion worth understanding. A tool that gives you a list of problems has moved the work to you and kept none of the risk. A tool that writes to your catalogue on its own has taken the work and handed you the risk. The card is the attempt at neither: the work is done, and the decision is still yours. We wrote up why that boundary is where it is, and where it comes from, &lt;a href="https://arvio.a.xyz/blog/why-fix-not-report?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_blog3" rel="noopener noreferrer"&gt;in a separate post on why this is a fix and not a report&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Every product in the catalogue, same shape&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One approval per change, and a diff you can read before you give it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-writes-the-fix&amp;amp;source_section=blog_mid&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_listing_mid" rel="noopener noreferrer"&gt;See Arvio on the Shopify App Store →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  After the button: what it tells you it did
&lt;/h2&gt;

&lt;p&gt;Pressing &lt;code&gt;Confirm Update&lt;/code&gt; runs the change. That's what makes this two rounds rather than one: the first produced the plan and the draft, and nothing else; the second is the one that writes. The result card reports back:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwsytuij9hjr4dke54qh4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwsytuij9hjr4dke54qh4.png" alt="The result card: a green check reading Description updated, the old and new descriptions, and a note that the action can be undone." width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three things on that card matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It confirms the scope it promised.&lt;/strong&gt; &lt;code&gt;All other products left untouched.&lt;/code&gt; The claim made before the change is the claim repeated after it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It shows the diff, not a success message.&lt;/strong&gt; &lt;code&gt;✓ Description updated&lt;/code&gt;, then &lt;code&gt;Old description&lt;/code&gt; struck through above &lt;code&gt;New description&lt;/code&gt; in full. You can read what landed without opening another tab. There's a &lt;code&gt;View in Shopify Admin →&lt;/code&gt; button for when you want to check the source of truth rather than take a card's word for it — which you should, and which is the whole reason that button exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It offers the way back.&lt;/strong&gt; In those words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This action can be undone. Let me know if you'd like to revert it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reversibility is what makes approving the first one bearable. If the cost of a bad rewrite is "fifteen minutes and some annoyance" rather than "find the original text, which you no longer have," then you'll actually try it on a real product instead of a test one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this run does not tell you
&lt;/h2&gt;

&lt;p&gt;Everything above is a recording of our own product on our own store, so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One product, one run.&lt;/strong&gt; This is not a sample. It says nothing about consistency across a catalogue, or about what the second hundred rewrites look like.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We didn't measure whether the new copy sells better.&lt;/strong&gt; No traffic, no conversion, no rankings. The 62-to-364 figure is a length, and length is not quality. A longer description that says nothing is worse than a short one that says something true.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's our own demo store&lt;/strong&gt;, stocked and described by us. Your catalogue is messier in ways ours isn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The recording is sped up.&lt;/strong&gt; The interface printed &lt;code&gt;39s&lt;/code&gt; and &lt;code&gt;22s&lt;/code&gt; against the two rounds; we're repeating what it displayed, not offering it as an independently timed benchmark. Either way, don't read the clip's length as wall time, and don't read any of this as real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judgment is still yours.&lt;/strong&gt; The tool can tell you a field is thin. It cannot tell you that the thin description was deliberate, that legal signed off on that exact wording, or that the product is being discontinued next week.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where this is actually useful
&lt;/h2&gt;

&lt;p&gt;The pitch is narrow.&lt;/p&gt;

&lt;p&gt;It is useful when you have a catalogue where a meaningful number of products have descriptions like that 62-character one — present, accurate, doing no work — and the reason they're still that way is that fixing them is typing, not deciding. That's the specific bottleneck: not knowing which products are thin, but that the fix for each one is a small writing job, and there are as many of them as you have products.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And that's the question this post can't answer for you.&lt;/strong&gt; We recorded one product. If you have four hundred, the honest read is that you'd be reading four hundred drafts and pressing the button four hundred times — approval is a real cost, and it scales with the catalogue exactly the way the typing did. What changes is the unit: reading something already written and deciding yes or no, rather than composing it from an empty box. Whether that trade is worth it at your catalogue size is a judgment we haven't measured and won't pretend to have.&lt;/p&gt;

&lt;p&gt;It is not useful when you already know the exact values you want in a column. A tag migration or a vendor rename is a spreadsheet operation. It's also not useful if every word needs legal sign-off, because then the approval queue is the bottleneck and moving work into it doesn't help.&lt;/p&gt;

&lt;p&gt;If you want the wider tour of what the thing does beyond this one interaction, &lt;a href="https://arvio.a.xyz/blog/what-arvio-actually-does?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_blog5" rel="noopener noreferrer"&gt;we wrote that up here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does it change anything before I approve it?&lt;/strong&gt;&lt;br&gt;
Not in this run. The confirmation card appeared with the draft in an editable box and nothing was written until &lt;code&gt;Confirm Update&lt;/code&gt; was pressed. That is the design: the card names its scope — &lt;code&gt;Only this product will be updated — all others left untouched.&lt;/code&gt; — before you decide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I edit what it wrote instead of accepting it?&lt;/strong&gt;&lt;br&gt;
Yes. The box is labelled &lt;code&gt;New Description (editable)&lt;/code&gt; and behaves like a text field. The draft is a starting point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I approve something and regret it?&lt;/strong&gt;&lt;br&gt;
The result card says &lt;code&gt;This action can be undone. Let me know if you'd like to revert it.&lt;/code&gt; We exercised the forward path in this recording and read the change back in the admin; we did not record a revert, so treat the undo as what the product offers rather than as something we demonstrated here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long did it take?&lt;/strong&gt;&lt;br&gt;
The interface displayed &lt;code&gt;39s&lt;/code&gt; and &lt;code&gt;22s&lt;/code&gt; against the two rounds. That's what it printed, not a number we timed ourselves. The clip is sped up for watching, so don't time it against the video, and don't read it as real-time — it's a job that runs, not a live edit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this a bulk editor?&lt;/strong&gt;&lt;br&gt;
No, and the distinction is the point. A bulk editor applies values you already decided to many rows at once. Here the missing piece isn't applying a decision, it's making one per product: what should this description say. That's why every change comes with a diff and an approval rather than a row count.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it write the same way for every product?&lt;/strong&gt;&lt;br&gt;
We ran one product. We can't tell you how consistent it is across a catalogue, and anyone quoting you a consistency figure from a single run is guessing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I have hundreds of products. Do I have to approve every single one?&lt;/strong&gt;&lt;br&gt;
In this recording, one change meant one approval. We haven't recorded what a few hundred look like, so we can't tell you there's a batch path or promise you there isn't — we'd rather say we don't know than guess on your behalf. Read the scale question as open, and size the trade yourself before you commit an afternoon to it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will better descriptions improve my traffic or sales?&lt;/strong&gt;&lt;br&gt;
We didn't measure that and this post doesn't claim it. What it establishes is the interaction shape: the change arrives written, scoped, and reversible.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Figures and quoted strings: one recorded run on our own demo store, 2026-09-21. Description lengths from the run's catalogue diff (62 → 364 characters stored). All on-screen text quoted verbatim from the recording. Last updated: 2026-09-21.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arvio: AI Store Operator — &lt;a href="https://apps.shopify.com/arvio?article_slug=arvio-writes-the-fix&amp;amp;source_section=blog_end&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_listing_end" rel="noopener noreferrer"&gt;install it on the Shopify App Store&lt;/a&gt;.&lt;/strong&gt; It goes through every product in the catalogue, one approval at a time.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arvio.a.xyz/blog/arvio-writes-the-fix?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_origin_foot" rel="noopener noreferrer"&gt;https://arvio.a.xyz/blog/arvio-writes-the-fix&lt;/a&gt;. More Shopify bulk-editing writeups are on &lt;a href="https://arvio.a.xyz/blog/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=devto_blog&amp;amp;utm_content=arvio-writes-the-fix_bloghome" rel="noopener noreferrer"&gt;the Arvio blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
