App Store Rejected Me for a Bug I Could Never Reproduce — Build Log #8
Business

App Store Rejected Me for a Bug I Could Never Reproduce — Build Log #8

"Tapped the Terms link, nothing happened." But it opened fine on my own iPhone. The cause was that review devices are managed devices. Then, after passing review, I made a much worse mistake.

KIYODO00
#solo dev#iOS#App Store#app review#build log

When I submitted my solo iOS app to the App Store, it was rejected under Guideline 2.1(a), App Completeness. The note read:

Tapped the in-app Privacy Policy / Terms of Use links, and nothing happened (unresponsive).

My honest first reaction was "that can't be right." On my own iPhone, those links open every single time.

The server was innocent and the code looked fine

The obvious suspect is the destination, but both the old and new domains responded normally. Server not guilty.

Then the code. The legal links used the most ordinary implementation there is: hand the URL to the system so an external browser opens it. On iOS, that's "pass this address to Safari." Nothing exotic.

And on my device, it worked. Nothing is worse than a bug that won't reproduce.

Root cause: the review device is a managed device

Here's where it landed.

The devices Apple uses for review can be organizationally managed (supervised / MDM). And on a managed device, handing off from an app to an external browser can be blocked.

So:

DeviceExternal browser handoffResult
My iPhone (unrestricted)allowedopens normally
Review device (managed)blockedtap does nothing

The code wasn't wrong. The server was fine. Only the environment's assumptions differed — and in review, that was fatal.

The fix: don't hand off, open in-app

The fix is simple: stop handing the URL to an external browser and open it inside the app instead. iOS provides a standard in-app browser for exactly this — a small browser surface that mounts inside your app. Nothing is handed outward, so a managed device has nothing to block.

I kept the external handoff as a fallback for when the in-app path fails.

I replaced all five legal links (three in settings, two required links on the paywall). The one exception is "Manage Subscription," which genuinely needs to reach Apple's own screen, so that one stays external on purpose.

Resubmitted, and it passed the next day.

One line:

In an app that goes through review, open legal and external pages with an in-app browser from the start. Don't assume external handoff is available.

Working on your device guarantees nothing about the review device. "I can't reproduce it" isn't a rebuttal — it's a signal to go looking for the environment difference.

Passing review was not the worst part

Being honest: I passed, and then found a much bigger mistake right after publishing.

The six screenshots on the store listing contained my own real data.

  • The task list showed my development to-dos ("add feature X," "think about the algorithm")
  • The notes screen showed personal errands — dentist, moving apartments
  • The billing screen showed developer-account numbers that make no sense on a free plan

The copy and keywords were fine. I'd simply never retaken the images. Shoot with your developer account and your private life ships as marketing material.

And I couldn't pull it down

I decided to remove it from sale and redo it — and got stuck. The "Remove from sale" button was disabled.

What I eventually learned: a brand-new app can't be pulled from sale until its initial release finishes propagating. It's Apple's rule. Clicking repeatedly wasn't going to help; it wasn't my mistake.

Worse, the version page displayed a banner saying the app had been removed from the App Store — while the actual availability settings showed published in all 175 territories. The dashboard contradicted reality, and trusting it would have led me to the wrong decision.

The saving grace: propagation hadn't finished, so the app wasn't findable in search yet — nobody had seen it. Zero actual harm.

Since waiting was the only option, I set up a job that checked the dashboard every two hours and clicked the button the moment it became enabled.

One more thing worth knowing in advance: you cannot swap screenshots on a live version. Retaking them means cutting a new version and going through review again.

Three traps solo developers walk into

  1. Links that depend on an external browser fail review. Different environment, different behavior.
  2. Shoot screenshots with dedicated demo data. Your own account puts your private life on the product page.
  3. You can't undo a launch immediately. Get it right before you ship — and don't trust the dashboard blindly.

All three sound obvious in hindsight. The reason obvious things slip is that you're the only one checking. The most expensive thing about solo development is the absence of another reviewer.

The app in this post

Everything above is from building THE TASK: AI To-Do Prep (App Store, free), an iOS app I develop solo. The idea is that AI fills a written task out until it's actually actionable. The rest of the series lives in the build log.

Comments (0)

No comments yet. Be the first to leave one.