DEV Community

shaojie gong
shaojie gong

Posted on

The Chrome Web Store rejected my extension for something it doesn't even do

The Chrome Web Store rejected my extension on the first try. The reason code was "Purple Potassium."

I stared at that for a while. I thought I'd misread the email. But no — Google labels its rejection reasons with these random color-and-element names, and mine was Purple Potassium, which is their tag for "excessive permissions." Somewhere at Google there's a spreadsheet where rejecting an indie developer's six months of work is filed under a name that sounds like a Crayola.

Here's the part that stung, though. They weren't rejecting me for something my extension did. They were rejecting me for two permissions I was requesting and never actually using: activeTab and scripting.

I didn't even remember adding them. That's the honest truth. Way back when I scaffolded the project, some starter template or some Stack Overflow answer told me a Chrome extension "usually needs" activeTab and scripting, so they went into the manifest and sat there for months. Never questioned. Never used. Just... declared, like a résumé listing a language you took one semester of in college and can't actually speak.

Before I touched anything, I made myself prove it. I've been burned enough times by "I'll just delete this, it's probably unused" — so I grepped the entire source tree. Every place those APIs could possibly show up: chrome.scripting, executeScript, insertCSS, chrome.tabs.query, the works. Zero hits. The only tab-related call in the whole codebase was chrome.tabs.create — the one that opens a URL in a new tab, which needs no permission at all.

Turns out my extension does its work through static content scripts declared right in the manifest. Those run automatically on the pages I list. They don't need activeTab (that's for grabbing temporary access on a user click) and they don't need scripting (that's for injecting code dynamically at runtime). I was carrying two heavyweight permissions to do a job that required neither.

So I deleted both lines. Bumped the version. Repackaged — and my pack script strips the manifest key on the way out, because the store rejects any upload that contains it. Re-submitted.

Five days later: approved. Published. Live.

And the whole way through, one thought kept circling: I didn't get rejected for what my product does. I got rejected for what it claimed it might do, and never did. The permissions weren't a feature. They were a liability I'd been carrying without noticing — extra surface area, extra reviewer suspicion, extra reason for a user to hesitate on the install screen. Deleting them didn't cost me a single feature. It made the product faster to review, cleaner to trust, and honestly, more honest.

That's a lesson that reaches way past a manifest file. Every capability you ask for that you don't use is a tax. On a résumé, on a startup's feature list, on a permission dialog — the stuff you request "just in case" isn't free optionality. It's weight. Reviewers, users, and hiring managers all read it the same way: why are you asking for this if you don't need it?

I wish the story ended at "approved." It didn't.

Because getting approved, it turns out, is just putting your thing on the shelf. It doesn't mean anyone walks down the aisle. I searched the store for my own extension, found it, and — it looked pathetic. Just a lonely little logo floating next to competitors with rich, colorful promo cards. Same as showing up to a job fair in a plain gray t-shirt while everyone else has a booth.

The store lets you upload a promo tile — a 440×280 image that becomes the big graphic on your search card. I built one: brand-orange gradient, the logo, a one-line pitch, three little feature pills. Made a 1400×560 marquee version too, for the day the store maybe features me. Went to upload them and got bounced again — the upload box only accepts 24-bit PNG with no alpha channel, and my files had transparency baked in. One flatten-and-remove-alpha later (channels: 4 → 3), they went through.

So here I am, actually launched. Smaller permissions, a real search card, and a much better understanding of a thing I'd gotten backwards: shipping isn't the finish line. It's the first day anyone can even find you.

If you've launched on a store — Chrome, Apple, Google Play, wherever — what's the thing you assumed was "done" at approval that turned out to be day one of the real work?

notebookbloom.com

— building NotebookBloom in public, #18

Top comments (0)