{"id":372469,"date":"2026-09-27T10:16:49","date_gmt":"2026-09-27T10:16:49","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/duplicate-sku-finder-for-woocommerce\/"},"modified":"2026-10-14T19:20:22","modified_gmt":"2026-10-14T19:20:22","slug":"merchlint-duplicate-sku-finder","status":"publish","type":"plugin","link":"https:\/\/fa.wordpress.org\/plugins\/merchlint-duplicate-sku-finder\/","author":23551451,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.2","stable_tag":"0.1.2","tested":"7.1.3","requires":"6.5","requires_php":"7.4","requires_plugins":null,"header_name":"Merchlint \u2013 Duplicate SKU and GTIN Finder for WooCommerce","header_author":"Baltano","header_description":"Finds products sharing an SKU, and products sharing or missing a GTIN. Read-only: it never writes to your catalogue.","assets_banners_color":"10527f","last_updated":"2026-10-14 19:20:22","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/merchlint.com\/duplicate-sku-finder\/","header_author_uri":"https:\/\/baltano.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":144,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.1":{"tag":"0.1.1","author":"baltano","date":"2026-09-27 10:16:31","revision":3715300},"0.1.2":{"tag":"0.1.2","author":"baltano","date":"2026-10-14 19:20:22","revision":3747019}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3715298,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3715298,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3715298,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3715298,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3715298,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.1","0.1.2"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3747016,"resolution":"1","location":"assets","locale":"","width":1440,"height":426},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3747016,"resolution":"2","location":"assets","locale":"","width":1280,"height":500},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3747016,"resolution":"3","location":"assets","locale":"","width":1440,"height":1159}},"screenshots":{"1":"The summary at the top of the results: one tile per check with the number of products it found,\nin the colour and word of what that number means - Important, Worth fixing, Clean or Not checked.","2":"Two checks up close: every finding shows the value that was read, with a link straight to the\nproduct in your admin.","3":"The whole results screen: the summary, the three checks and the CSV export."}},"plugin_section":[],"plugin_tags":[264211,11082,148700,286809,54047],"plugin_category":[45],"plugin_contributors":[278694],"plugin_business_model":[],"class_list":["post-372469","plugin","type-plugin","status-publish","hentry","plugin_tags-duplicate-sku","plugin_tags-ean","plugin_tags-gtin","plugin_tags-invalid-sku","plugin_tags-upc","plugin_category-ecommerce","plugin_contributors-baltano","plugin_committers-baltano"],"banners":{"banner":"https:\/\/ps.w.org\/merchlint-duplicate-sku-finder\/assets\/banner-772x250.png?rev=3715298","banner_2x":"https:\/\/ps.w.org\/merchlint-duplicate-sku-finder\/assets\/banner-1544x500.png?rev=3715298","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/merchlint-duplicate-sku-finder\/assets\/icon.svg?rev=3715298","icon":"https:\/\/ps.w.org\/merchlint-duplicate-sku-finder\/assets\/icon.svg?rev=3715298","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/merchlint-duplicate-sku-finder\/assets\/screenshot-1.png?rev=3747016","caption":"The summary at the top of the results: one tile per check with the number of products it found,\nin the colour and word of what that number means - Important, Worth fixing, Clean or Not checked."},{"src":"https:\/\/ps.w.org\/merchlint-duplicate-sku-finder\/assets\/screenshot-2.png?rev=3747016","caption":"Two checks up close: every finding shows the value that was read, with a link straight to the\nproduct in your admin."},{"src":"https:\/\/ps.w.org\/merchlint-duplicate-sku-finder\/assets\/screenshot-3.png?rev=3747016","caption":"The whole results screen: the summary, the three checks and the CSV export."}],"raw_content":"<!--section=description-->\n<p>Two products with the same SKU throw off stock levels, integrations and every export file your store\nproduces. Two products with the same GTIN tell a shopping service they are the same item, so one of\nthem quietly disappears from search. A product with no identifier at all usually drops out of the\nfeed altogether.<\/p>\n\n<p>None of this breaks your store, which is why it goes unnoticed for years. Nothing in the WooCommerce\nadmin points at any of it.<\/p>\n\n<p>This plugin checks three things and nothing else:<\/p>\n\n<ul>\n<li><strong>Two products share the same SKU.<\/strong> Translations of one product are not counted as a duplicate \u2014\na multilingual store gives every translation the same code on purpose, and reporting that pair\nwould be a false alarm. We read the translation groups of Polylang and WPML.<\/li>\n<li><strong>Product with no GTIN, UPC, EAN or ISBN.<\/strong> Stays quiet in shops that do not use identifiers at\nall: if not one product has the field filled, you get a single sentence saying so instead of a\nlist of your entire catalogue. Handmade goods, services and your own production carry no\nmanufacturer's barcode and need none.<\/li>\n<li><strong>Two products share the same identifier.<\/strong><\/li>\n<\/ul>\n\n<h4>What it does not do<\/h4>\n\n<p>It <strong>never writes to your catalogue<\/strong>. There is no \"Fix it\" button, and there will not be one: a\nbulk change to product data is not something a report should do on your behalf. Every finding shows\nthe value that was read, so you can check the claim before you act on it.<\/p>\n\n<p>It reads no order data, which makes the scan far cheaper than a full audit. The scan still runs\nin a single request, so on a very large catalogue it can run into your host's time limit \u2014 the\nscreen says so when that becomes likely, and the WP-CLI command has no such limit.<\/p>\n\n<h4>Evidence, not adjectives<\/h4>\n\n<p>Every finding shows the field that was read and the value found, with a link straight to the product\nin your admin. A rule that could not run says so by name \u2014 on WooCommerce older than 9.2 the\nidentifier field does not exist at all, and the report says that rather than reporting every product\nas faulty.<\/p>\n\n<h4>Where the audit engine comes from<\/h4>\n\n<p>The scanning engine is the one behind Merchlint, a full WooCommerce catalogue audit from the same\nauthor. This plugin carries its own copy with its own class names, so both can run side by side.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate.<\/li>\n<li>Open <strong>Tools \u2192 Duplicate SKU and GTIN Finder<\/strong>.<\/li>\n<li>Press <strong>Scan now<\/strong>.<\/li>\n<\/ol>\n\n<p>For large catalogues there is a WP-CLI command: <code>wp merchlint-duplicate-sku-finder scan<\/code>.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20i%20find%20duplicate%20skus%20in%20woocommerce%3F\"><h3>How do I find duplicate SKUs in WooCommerce?<\/h3><\/dt>\n<dd><p>Install this plugin, open <strong>Tools \u2192 Duplicate SKU and GTIN Finder<\/strong> and press <strong>Scan now<\/strong>. Every\nproduct that shares its SKU with another one is listed with the SKU that was read and an Edit link,\nand <strong>Download CSV<\/strong> gives you the same list as a file. It compares published products and their\nvariations; translations of one product are not counted as duplicates.<\/p>\n\n<p>WooCommerce itself refuses a repeated SKU when you save a product, but it has no screen that lists\nthe pairs already in your catalogue. Those got in another way - for example through a tool that\nwrites to the database directly.<\/p><\/dd>\n<dt id=\"what%20does%20%22invalid%20or%20duplicated%20sku%22%20mean%3F\"><h3>What does \"Invalid or duplicated SKU\" mean?<\/h3><\/dt>\n<dd><p>WooCommerce shows this message when you save a product with an SKU that another product or\nvariation already has. A draft or a private product holds its SKU too; only a product in the Trash\ndoes not. In the classic product editor your other changes are saved, and the SKU keeps its\nprevious value.<\/p>\n\n<p>To find the product that holds it, type the SKU into the search box under\n<strong>Products \u2192 All Products<\/strong>. That search covers drafts, private products and the SKUs of variations,\nand for a variation it shows the product the variation belongs to. This plugin lists published\nproducts and their variations only, so a draft holding the SKU will not be on its list.<\/p>\n\n<p>The identifier field has its own version of the message, \"Invalid or duplicated GTIN, UPC, EAN or\nISBN.\" (WooCommerce 9.2 and later), and it works the same way.<\/p>\n\n<p>Since WooCommerce 11.2 the product CSV importer, with <strong>Update existing products<\/strong> ticked, also\nfinds products by their GTIN. A row whose GTIN two products share fails with this message, and\nneither product changes; the importer does not say which product holds the other copy. The list\nfrom this plugin shows which published products share it.<\/p><\/dd>\n<dt id=\"how%20do%20i%20find%20woocommerce%20products%20without%20a%20gtin%3F\"><h3>How do I find WooCommerce products without a GTIN?<\/h3><\/dt>\n<dd><p>Since WooCommerce 9.2 every product has a field for a GTIN, UPC, EAN or ISBN, but nothing in the\nadmin lists the products where it is empty. This plugin does: each one with an Edit link, and a\nvariable product once, with the number of its variations that have no code.<\/p><\/dd>\n<dt id=\"how%20do%20i%20check%20if%20a%20gtin%20or%20ean%20is%20valid%3F\"><h3>How do I check if a GTIN or EAN is valid?<\/h3><\/dt>\n<dd><p>This plugin does not check the number itself. It finds products with no GTIN and GTINs used by more\nthan one product. To check the check digit, the length and the format of a whole list of codes, use\nthe free <a href=\"https:\/\/merchlint.com\/gtin-validator\/\">GTIN validator<\/a> on our website: paste a column of\ncodes or pick a product export file (CSV, TXT or XLSX). It runs in your browser, and the file is not\nsent anywhere.<\/p>\n\n<p>A well-formed number is not yet proof that it belongs to the product. Only the GS1 registry shows\nwhether the manufacturer registered it.<\/p><\/dd>\n<dt id=\"does%20it%20change%20anything%20in%20my%20shop%3F\"><h3>Does it change anything in my shop?<\/h3><\/dt>\n<dd><p>No. It reads the catalogue and writes nothing back. It keeps two things of its own: the last result,\nso that reloading the page does not require another scan, and - once you answer the review request\nunder the results - a note in your user profile, so that the request does not come back. Deleting the\nplugin removes both.<\/p><\/dd>\n<dt id=\"my%20shop%20is%20multilingual.%20will%20translations%20be%20reported%20as%20duplicates%3F\"><h3>My shop is multilingual. Will translations be reported as duplicates?<\/h3><\/dt>\n<dd><p>No. Translations of one product share an SKU on purpose, and the check treats one translation group\nas one product. Polylang and WPML are both read.<\/p><\/dd>\n<dt id=\"i%20do%20not%20use%20gtins%20at%20all.%20will%20i%20get%20a%20list%20of%20every%20product%3F\"><h3>I do not use GTINs at all. Will I get a list of every product?<\/h3><\/dt>\n<dd><p>No. If not one product in the catalogue has the field filled, the check stays quiet and tells you\nwhy, in one sentence.<\/p><\/dd>\n<dt id=\"can%20an%20ai%20assistant%20read%20the%20results%3F\"><h3>Can an AI assistant read the results?<\/h3><\/dt>\n<dd><p>Only if you connect one yourself. On WordPress 6.9 or later the plugin registers two read-only\nabilities through the WordPress Abilities API: the summary of the last scan and the list of its\nfindings. An AI assistant you connect to your store, for example through an MCP plugin, can call\nthem as a logged-in user with the <code>manage_woocommerce<\/code> permission, and gets the same results as\nthe Tools screen. The plugin itself sends nothing anywhere and changes nothing in your shop.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.2<\/h4>\n\n<ul>\n<li>A summary at the top of the results: one tile per check with the number of products it found,\ncoloured by what that number means - Important, Worth fixing, Clean or Not checked - and linked to\nthe check below it. The colours and words are the same as in the Merchlint store audit.<\/li>\n<li>After a scan, a one-time request for a review on WordPress.org, below the results and never above\nthem. Writing the review or pressing \"Don\u2019t ask again\" closes it for good, for your user only.\nDeleting the plugin removes this note too.<\/li>\n<li>SKUs and GTINs are compared the same way on every database. A code that came with an invisible\ncharacter or a non-breaking space - common when it is pasted from a spreadsheet - is now the same\ncode as the one without it. Until now this depended on the database behind the shop: on MySQL 8\nsuch a duplicate was missed, or only one product of the pair was listed. A GTIN field holding\nnothing but such characters now counts as empty.<\/li>\n<li>Invisible characters in product codes now show in the evidence. Two codes that differ only by a\nnon-breaking space or a zero-width character look the same on screen, so a pair of duplicates\ncould show one value twice. The evidence now writes each such character as \u27e8U+00A0\u27e9 and\nsimilar, on the screen and in the CSV export. Clean codes look exactly as before.<\/li>\n<li>\"Product with no GTIN, UPC, EAN or ISBN\" no longer lists gift cards. Gift card products from gift\ncard plugins have no barcode by nature.<\/li>\n<li>Accessibility: each Edit link now also gives the product ID to a screen reader. A duplicate SKU\nusually comes from copying a product, and the copy keeps the name - so two links read out as the\nsame \"Edit\" led to two different products.<\/li>\n<li>Two read-only abilities for AI assistants (WordPress Abilities API, WordPress 6.9 or later): the\nsummary of the last scan and the list of its findings. An assistant you connect to your store\nyourself, for example through an MCP plugin, reads them with the same permission as the Tools\nscreen; the plugin sends nothing anywhere.<\/li>\n<\/ul>\n\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Renamed on the request of the plugin directory review: the display name now leads with the\nMerchlint brand, and the slug and text domain are \"merchlint-duplicate-sku-finder\".<\/li>\n<li>One name for everything, so nothing is left half-renamed: the WP-CLI command is now\n  wp merchlint-duplicate-sku-finder scan, the screen sits at\nTools -&gt; Duplicate SKU and GTIN Finder (tools.php?page=merchlint-duplicate-sku-finder) and the\nexport is saved as merchlint-duplicate-sku-finder.csv. The checks, the findings and the columns\nof the CSV file are unchanged.<\/li>\n<li>The name also says what the plugin actually looks at: duplicate SKUs and duplicate or missing\nproduct identifiers, not SKUs alone.<\/li>\n<li>Accessibility: the table headers now carry <code>scope<\/code>, and each Edit link says which product it\nedits, so a screen reader no longer reads eight links called only \"Edit\".<\/li>\n<li>Declared compatibility with the Cart and Checkout blocks, next to the existing High-Performance\nOrder Storage declaration. The plugin adds nothing to the front end; without the declaration\nWooCommerce listed it among extensions of uncertain compatibility.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>First release. Duplicate SKU, missing GTIN and duplicate GTIN, with evidence on every finding,\nCSV export and a WP-CLI command.<\/li>\n<\/ul>","raw_excerpt":"Finds products sharing an SKU, and products sharing or missing a GTIN. Read-only: it never writes to your catalogue.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/372469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=372469"}],"author":[{"embeddable":true,"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/baltano"}],"wp:attachment":[{"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=372469"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=372469"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=372469"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=372469"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=372469"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/fa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=372469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}