<?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: Jason Pun</title>
    <description>The latest articles on DEV Community by Jason Pun (@jasonpun).</description>
    <link>https://dev.to/jasonpun</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%2F4025108%2F56568595-2894-4aab-a0ec-6309357edeab.png</url>
      <title>DEV Community: Jason Pun</title>
      <link>https://dev.to/jasonpun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jasonpun"/>
    <language>en</language>
    <item>
      <title>How a "safe" shipping change silently disapproved 621 products in Google Merchant Center</title>
      <dc:creator>Jason Pun</dc:creator>
      <pubDate>Sat, 11 Jul 2026 23:23:31 +0000</pubDate>
      <link>https://dev.to/jasonpun/how-a-safe-shipping-change-silently-disapproved-621-products-in-google-merchant-center-i12</link>
      <guid>https://dev.to/jasonpun/how-a-safe-shipping-change-silently-disapproved-621-products-in-google-merchant-center-i12</guid>
      <description>&lt;p&gt;I run a small Shopify store. One afternoon I split my shipping policy in two — separate rules for domestic vs. international, nothing exotic — and by the next morning &lt;strong&gt;621 of 739 active products&lt;/strong&gt; had been disapproved in Google Merchant Center. A 21% drop became an 84% drop overnight, and the actual error Google returned was &lt;code&gt;missing_shipping&lt;/code&gt;, which made no sense: the products had shipping info, I'd just moved it.&lt;/p&gt;

&lt;p&gt;This is the write-up of what actually went wrong and how I built a small diagnostic tool to catch it faster next time, because the failure mode is common and the fix is a five-minute mistake to make.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "missing_shipping" was lying to me
&lt;/h2&gt;

&lt;p&gt;Google's Merchant Center UI reports the symptom, not the cause. &lt;code&gt;missing_shipping&lt;/code&gt; reads like "this product has no shipping rate," but what had actually happened was a sync-order race: I split delivery into two policies (domestic / international) in Shopify admin, and Google's feed re-sync started reading the new policy structure &lt;em&gt;before&lt;/em&gt; both new policies had propagated rates for every product. For a window of time, some products resolved to a policy that had no rate defined yet for their destination — which Google reports identically to "no shipping info at all."&lt;/p&gt;

&lt;p&gt;The fix, once I understood it, was almost insultingly simple: collapse both policies back into one — "All products + Free delivery" — so there's only one rate resolution path, no race, no partial-propagation window. Approved count went 582 → 739 within a day of the resync.&lt;/p&gt;

&lt;p&gt;The part that actually cost time wasn't the fix. It was figuring out that a &lt;em&gt;shipping settings change&lt;/em&gt; was the cause of a &lt;em&gt;content-status disapproval&lt;/em&gt;. Nothing in the Merchant Center UI connects those two. You have to already suspect account settings, not the feed itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tool I built afterward
&lt;/h2&gt;

&lt;p&gt;I didn't want to diagnose this by memory next time, so I built a small script-based toolkit against the Merchant Center API (Content API v2 / Merchant API) that does the diagnosis Google's own dashboard doesn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Groups every disapproval by root cause, not by product — so instead of scrolling 621 individually-flagged products, you see "1 root cause, 621 symptoms"&lt;/li&gt;
&lt;li&gt;Separates NOT_IMPACTED warnings (Google's own "this doesn't hurt you yet" flag) from actual SHOPPING_ADS/FREE_LISTINGS disapprovals, because a lot of noise in a typical feed dashboard is cosmetic&lt;/li&gt;
&lt;li&gt;Distinguishes surface-specific disapprovals (YouTube/Demand-Gen only vs. core Shopping) so you don't burn an afternoon fixing something with zero current revenue impact because the ad campaign using that surface is paused anyway&lt;/li&gt;
&lt;li&gt;Checks account-level settings (shipping, tax, business info) as a first-class diagnosis step, not an afterthought, specifically because of incidents like this one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On a later, smaller incident on the same store — 49 flagged products in one week — the tool traced the whole thing down to exactly &lt;strong&gt;one real revenue-impacting product&lt;/strong&gt; (a category-classifier false positive reading "tea tree" + no product category as a pharma/medical listing). The other 48 were self-clearing pending-review states or YouTube-only warnings with paused campaigns behind them. Knowing which 1 out of 49 actually mattered was the entire value of the exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  The general lesson
&lt;/h2&gt;

&lt;p&gt;If you sell on Shopify + Google Shopping and you ever touch shipping policies, tax settings, or return policies at the account level, treat it as a feed-risk change, not a settings change — even if nothing in the UI warns you it's connected to disapprovals. Merchant Center's error messages describe symptoms at the offer level; the actual root causes are disproportionately often account-level settings, classifier false positives on ambiguous wording, or a stale supplemental data source nobody remembers is still live.&lt;/p&gt;

&lt;p&gt;I packaged the diagnostic + fix-module toolkit as &lt;a href="https://www.puniverse.net/product/gmc-feed-doctor" rel="noopener noreferrer"&gt;GMC Feed Doctor&lt;/a&gt; if you want the agentic version of this — it's the same root-cause-first approach, proven on the exact 621-product incident above, plus 8 fix modules for the common repeat offenders (identity/GTIN, shipping labels, unit pricing, category coverage, sale-price display, image/content policy).&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>shopify</category>
      <category>seo</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
