This page is available in English only; the English version prevails.
All postsThree Chrome Web Store rejections and the fixes
By Tiger Liu · · 4 min read
Between late July and early September 2026 I shipped a batch of Chrome extensions, and the Chrome Web Store sent several of them back. The rejection emails give you a violation code and a one-line reason, which is rarely enough to know what to change. This is what the three codes I hit turned out to mean in practice, and what I changed each time.
Yellow Argon: repetition, not the words themselves
AI Chat Exporter was rejected on its first submission on August 10 with Yellow Argon: "excessive and/or irrelevant keywords in the product description."
My first reading was that I had used a banned word. I hadn't. When I lined up the flagged sections, every one of them was the same set of proper nouns in a comma-separated string: the names of the supported chat platforms appeared three times, the list of export formats appeared three times, and all thirteen interface languages were listed once. None of the words was a problem on its own. The repetition was.
The fix for that version (0.1.0 → 0.1.1) was to rewrite the listing in all thirteen languages:
- The name lost its keyword tail and became simply "AI Chat Exporter by Xeviora".
- The short description stopped listing platforms and kept only two format names.
- The long description mentioned each platform once, inside a normal sentence, and described the rest of the formats in words instead of a list.
- The promo images were re-rendered too. Store images are read with OCR, so a chip row of format names on a banner counts as keyword text.
Because the extension name and description live inside the package, this needed a new version upload, not just a listing edit.
It was rejected again two days later, with the same code. "Once each, written as a sentence" was still too much: a single sentence that names six third-party brands reads as a keyword list no matter how it is phrased. The rule I wrote into the store checklist afterwards is stricter: zero third-party product names in the listing. Which sites the extension works on is already visible in Chrome's own site-access list, in the screenshots of the product UI, and on the product page. The same review also made me check the screenshots themselves: a real platform domain in a browser address bar is text the OCR will pick up.
Red Nickel: "Free" is a promotional word
Red Nickel covers promotional language. The obvious offenders are "best" and "#1". The one that caught ScrnCap was "Free".
Two details made this harder than deleting one word from the description:
- The OCR reads the extension's own UI. Screenshots are part of the listing, so every "Free" inside the popup or the settings page counts. For Bookmark Commander I rewrote 138 strings across 12 languages into factual phrasing such as "5 local tools · no account" and "run locally at no cost", re-captured all five screenshots, and added a test assertion that fails if
\bfree\bshows up again on the upgrade screen. - Translations count. ScrnCap ships a listing in 27 languages. Removing "Free" from the English text did nothing about "Gratis", "무료" or "免费". I replaced those in all 27 languages (along with "New", which is in the same category), and even rewrote an innocent-looking "account-free".
Because a keyword list only in English cannot catch translated promotional words, the store folder now has a validate.mjs script with a second word list covering the translated forms — مجان, darmow, zdarma, ilmai, ücretsiz, δωρεάν, ฟรี, 무료, 免费 and more. Running it is now a step in the upload checklist.
Purple Potassium: a permission you declare but never call
ReelCap 1.0.0 was rejected on September 3 with Purple Potassium: requesting a permission that is not used.
The permission was downloads. I had added it early on, assuming I would save recordings through chrome.downloads. In the end the preview page saves files with a plain <a download> link, which needs no permission at all. Nothing in the code called chrome.downloads.*, but the manifest still asked for it.
The fix itself was one line in the manifest, released as 1.0.1. What took longer was everything that describes the permissions: the justification text in the review form, the permission table in the privacy policy, and the permission list on the product site. I also went through the remaining seven permissions and the host permission one by one and confirmed each has a real call site, rather than risk a second round of the same rejection.
What I do differently now
- Treat the listing as a data file with its own tests. The name, descriptions and promo text for every language live in the repository and go through the same validation script before upload.
- Assume everything visible is text. Screenshots, promo tiles and address bars are all read by OCR.
- Audit permissions against call sites before each submission, not after a rejection.
- Write the rule down the day you learn it — and make it a script. A note in a checklist did not stop ScrnCap from repeating a mistake Bookmark Commander had already fixed; a validation script that fails the upload would have.
If you want to see how these extensions have changed since, every update is logged on the changelog. AI Chat Exporter, the one that went through Yellow Argon twice, is on its product page.
Mentioned in this post
每月一封,幕后实录
旗下每个产品上线了什么、哪些做法有效、哪些翻了车。每月一封,仅此而已。