# Skill: Eliminate the six most common store rejection causes before submitting an app > Lets an AI coding/design agent run a pre-submission sweep that closes the six traps — crashes, placeholders, broken links, missing privacy policy, misleading screenshots, and unnecessary permissions — that account for the majority of App Store and Google Play rejections. Source: sodigi·learn — publish/chastye-prichiny-otkaza · https://sodigi.io/learn/publish/chastye-prichiny-otkaza ## When to use - Any build is about to be submitted to the App Store or Google Play. - A build was rejected and the developer needs to know what to look for. - The app was generated or scaffolded with AI tooling (vibe-coded), which tends to leave placeholders, extra permissions, and untested flows. - Performing a code review before the final release build is produced. ## Core rules - App store reviewers are real people with a checklist who actively look for reasons to reject; do not hand them any. - A single crash on any screen the reviewer opens = instant rejection with no partial credit. - Every UI element reachable from the first screen must do something real — no placeholders, no "Coming soon", no lorem ipsum, no gray image squares. - Every link in the app and in the store listing must open the correct destination. The privacy policy link is the most-checked single URL. - A privacy policy page is required for nearly every app; the link must appear in both the store listing metadata AND inside the app. - Screenshots in the listing must show exactly what is in the submitted build — no features from the future, no Photoshop enhancements. - Permissions must be limited to what the app actually uses right now, each with a plain-language usage description. - Test on a FRESH INSTALL with no pre-existing data, no pre-granted permissions, and no seed accounts — that is exactly what the reviewer sees. - AI-generated code routinely introduces placeholder screens and excess permissions "just in case"; audit both explicitly. ## Procedure 1. Fresh-install the release build on a clean device (or a clean simulator/emulator with no test data). Log nothing in from existing credentials. 2. Walk the entire user flow from first launch: onboarding, login/signup, empty states, main features, settings, any paywall. Record every crash, freeze, or non-functional tap. 3. Fix all crashes and freezes before any other step — stability is the highest-priority check. 4. Search the codebase and visible UI for every placeholder: "Coming soon", "TODO", "lorem ipsum", gray box images, dead buttons, empty tabs. Remove or replace each one. 5. Open every link in the app and in the draft store listing manually. Click the privacy policy link, support link, and any in-app URL. Confirm each opens the correct live page (no 404, no localhost, no password gate). 6. Confirm a privacy policy page exists at a stable public URL. The URL must appear in the store listing metadata AND be accessible from within the app (e.g., in Settings or onboarding). 7. Take new screenshots directly from the current build on a real device or simulator. Remove any screenshot that shows a feature not in the build or uses Photoshop enhancements beyond basic cropping. 8. Open the app's permission manifest (AndroidManifest.xml, Info.plist, or equivalent). For each permission, confirm it is actively used in the current build. Remove any permission that is not used. Verify every used permission has a clear usage description string. 9. Run through the checklist one more time as a final gate, then produce the release build and submit. ## Ready-to-use prompt ``` Review my app before I submit it for review in the App Store and Google Play. Find and list everything that could trigger a rejection across these six categories: 1. Crashes and bugs: identify any screen, flow, or state (empty data, offline, first launch, login) that crashes or visibly malfunctions. Include file and line number where possible. 2. Placeholders: find every instance of "Coming soon", lorem ipsum, gray placeholder images, dead buttons, empty tabs, or TODO notes visible to the user. List each with its location in the code. 3. Broken links: list every URL in the app and in the store listing (including the privacy policy link). Flag any that is a localhost address, a draft URL, a 404, or a link behind a login gate. 4. Privacy policy: confirm a privacy policy link exists, is publicly accessible without login, and appears in both the store listing metadata and inside the app. If either location is missing, tell me where to add it. 5. Misleading screenshots: compare the current store listing screenshots against the build. Flag any screenshot that shows a feature not present in the build or that has been edited beyond basic device frame cropping. 6. Unnecessary permissions: list every permission declared in the manifest or Info.plist. For each one, state whether it is actively used in the current build. Flag any that are declared but unused. For every finding: where it is, why it causes a rejection, and the minimum change to fix it. Do not invent problems that are not there. ``` ## Pitfalls - Testing only on your own development device — you already have all permissions granted, all data seeded, and every account logged in; the reviewer starts from zero. - Leaving AI-generated placeholder screens in the release build — vibecoded apps routinely ship with skeleton UIs; always audit by running the app as a first-time user. - Not clicking the privacy policy link manually before submitting — a single broken URL is a complete rejection; verify it opens in incognito. - Using designer mockup screenshots instead of real build screenshots — screenshot deception is a fast rejection and harms user trust. - Requesting permissions "just in case" from a generated template — unused permissions are a red flag; remove every permission the app does not actively use. - Treating a rejection as a crisis instead of a checklist item — read the rejection reason precisely, fix the specific item cited, and resubmit; do not guess at additional changes.