◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 31 days left. If your app calls it, check the migration target●SDK 58 ISSUE — Early reports include Android widgets not refreshing on a schedule and Stripe linking statically●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 31 days left. If your app calls it, check the migration target●SDK 58 ISSUE — Early reports include Android widgets not refreshing on a schedule and Stripe linking statically●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-06-17Intermediate

Your Rork App Is Stuck on "Processing" in App Store Connect — A Field Guide to Getting It Unstuck

You uploaded a Rork-built app to App Store Connect, but the build sits on Processing for hours and never shows up in TestFlight or for submission. Here is the exact diagnostic order I follow, how to read the ITMS error codes, and a short script that reads the processing state from the API — with working code.

Rork611App Store Connect17TestFlight16ProcessingTroubleshooting54

The upload bar hits 100%, you see "successfully delivered," and then... nothing. You open the TestFlight tab in App Store Connect and the build simply isn't there. The status reads "Processing," and thirty minutes later it still reads "Processing." An hour later, still nothing. Running several apps in parallel, I have been stuck at exactly this screen more than once.

What makes it frustrating is the silence. The upload succeeded, so there is no error message pointing you anywhere. The build just quietly stays in Processing, and the submit-for-review button stays out of reach.

What follows is what I actually do when an app exported from Rork (the React Native / Expo flavor) or Rork Max (the native Swift one) gets stuck processing in App Store Connect — the order I diagnose it in, and how I fix each cause. These are only the routes I have personally gotten unstuck on, not generic theory.

First, separate the two kinds of "Processing"

The thing to internalize up front is that "Processing" actually covers two very different internal states.

The first is the normal one: Apple's servers are unpacking and validating the binary you sent. That usually finishes in 5–15 minutes, or up to 30 when things are busy. Right after a new Xcode or SDK release, uploads from all over the world pile up, so the queue genuinely gets longer.

The second is the one that hurts: validation found a problem, and Apple treats it not as an outright rejection but as a silent stall. The status sits on Processing indefinitely, or the build disappears a few hours later. With Rork-exported apps, the cases that bit me were almost always this second kind.

So the first move is a judgment call: if it hasn't changed after 30 minutes, it is not a normal queue. Waiting longer won't fix it, so switch to finding the cause.

Check your registered email and the build's "Activity"

Even when nothing shows on screen, Apple often emails the person on the account when it finds a problem. More than once, my TestFlight tab showed nothing while my inbox already held a message from "App Store Connect" spelling out the exact rejection reason.

Here is the order I check.

First, look at the inbox — and the spam folder — of the email registered to your Apple Developer account. Then in App Store Connect, open the app → TestFlight → the build's Activity, and the notification bell in the left menu. If an email arrived, it will name either an ITMS error code or an Invalid Binary reason.

The email itself is long, but the only part worth reading is the ITMS number. These are the codes I have actually received for Rork-exported apps, and which section of this article each one points to.

CodePhrase in the subject lineWhat it meansSection
ITMS-90717Invalid App Store IconThe 1024×1024 icon still has an alpha channelCause 2
ITMS-90189Redundant Binary UploadThe same version × build number was uploaded twiceCause 3
ITMS-90725SDK version issueBuilt with an Xcode older than the required SDKCause 4
ITMS-90683Missing Purpose StringA usage description (camera, photos, …) is missing from Info.plistCause 4 (separate article)

If you find your cause here, you can skip the rest. Only move on if nothing arrived.

Cause 1: Missing encryption export compliance

This is the one I have hit most often with Rork-exported apps. An app counts as "using encryption" merely by talking over HTTPS, which triggers an export compliance declaration. When that declaration is missing, the build tends to stall in Processing.

The permanent fix is to bake the declaration into app.json (Expo) or Info.plist (Swift). If your app only uses standard encryption (HTTPS), this one line frees you from being asked at every single upload.

For Expo (app.json):

{
  "expo": {
    "ios": {
      "config": {
        "usesNonExemptEncryption": false
      }
    }
  }
}

For Swift, add the key directly to Info.plist:

<key>ITSAppUsesNonExemptEncryption</key>
<false/>

You may set this to false only if you have not implemented your own custom encryption and rely solely on the OS's standard HTTPS and standard crypto APIs. If your app ships proprietary encryption, do not casually set false — check Apple's export compliance requirements first. With this line in place, future uploads are far less likely to stall, and you skip the manual declaration each time.

Cause 2: A missing, transparent, or wrong-sized icon

Stuck on Processing, then the build vanishes a few hours later — one cause I tracked down for this pattern was the icon. If your 1024×1024 App Store icon contains an alpha channel (transparency), validation rejects it. No on-screen error appears; the build just never shows up.

You can check this with one command. To see whether the icon has transparency, run:

# Check whether the icon contains an alpha channel
sips -g hasAlpha AppIcon-1024.png
# If the output says "hasAlpha: yes", transparency is still present

If transparency remains, re-export the icon flattened onto an opaque background such as white:

# Flatten transparency onto a white background and produce an opaque PNG (ImageMagick)
magick AppIcon-1024.png -background white -alpha remove -alpha off AppIcon-1024-fixed.png

If you're on Expo's managed workflow, make the source image referenced by ios.icon in app.json opaque, and the build will generate a correct icon set. Rork's auto-generated placeholder icons sometimes keep their transparency, so I always swap them out before publishing.

When I replaced the icon on one of my wallpaper apps, it took two vanished builds before I noticed the export dialog still had "transparent background" ticked. The picture looked identical; the file underneath was not.

Cause 3: A duplicate build number

You cannot upload the same version × build number combination twice. Yet the upload itself can still succeed and appear to hang in Processing — when in reality the build collided with an existing one and was discarded.

To avoid this, I keep the build number strictly increasing. With Expo's EAS Build, remote auto-numbering is the reliable setup:

{
  "cli": {
    "appVersionSource": "remote"
  },
  "build": {
    "production": {
      "autoIncrement": true
    }
  }
}

If you manage numbers by hand, check the latest build number in App Store Connect before uploading and always go higher. When you bump the version, resetting the build number to 1 is fine — but never duplicate a build number within the same version.

Cause 4: An old SDK, missing dSYMs, or an invalid binary — the "silent rejection"

The last pattern, where processing drags on and the build then disappears, is the binary failing validation itself. A missing dSYM for crash collection, or an unsupported architecture slipping in, leads Apple to mark it invalid. Often you get an email; sometimes you don't.

The cause that has grown since the start of 2026 is an outdated SDK. Per Apple's published requirements, since April 28, 2026, apps uploaded to App Store Connect must be built with Xcode 26 (the iOS 26 SDK) or later. Export from a Mac whose Xcode you forgot to update and you'll either get ITMS-90725 (SDK version issue) or watch the build disappear without any notice. If you build on EAS, it's worth checking once a year that the image in eas.json isn't still pinned to an older Xcode. What happens when you build against a beta SDK is a different story, and I've written it up separately in An app built with a beta SDK can go to TestFlight — but not to review.

What helps here is validating locally before you upload. Once the .ipa exists, running it through altool gives you the same kind of validation result without waiting on App Store Connect:

# Validate the binary locally before uploading
xcrun altool --validate-app \
  -f build/MyApp.ipa \
  -t ios \
  --apiKey "YOUR_KEY_ID" \
  --apiIssuer "YOUR_ISSUER_ID"

If this returns an error, you learn the cause before spending hours watching Processing. Since I started adding this one validation step to my release flow, the "I uploaded it but it vanished" incidents have nearly disappeared. Even when export-to-submit is fully automated — as with Rork Max's two-click publishing — it's reassuring to leave room to validate the generated .ipa once on your own machine.

Instead of watching the screen, ask the API for the processing state

Reloading a browser tab over and over is the part that wears me down most. What I do now is read the latest build's processingState from the App Store Connect API. It has four values — PROCESSING, VALID, FAILED, and INVALID — and the API distinguishes FAILED and INVALID, which the web UI never shows you.

Issue an API key under Users and Access → Integrations in App Store Connect, and keep the .p8 file together with the Key ID and Issuer ID. The smallest working version in local Python looks like this:

# asc_build_state.py — read the latest build's processingState from the App Store Connect API
# Setup: pip install pyjwt cryptography requests
import sys
import time
 
import jwt
import requests
 
KEY_ID = "YOUR_KEY_ID"
ISSUER_ID = "YOUR_ISSUER_ID"
PRIVATE_KEY_PATH = "AuthKey_YOUR_KEY_ID.p8"
APP_ID = "YOUR_APP_ID"  # the numeric "Apple ID" shown in App Store Connect
 
 
def make_token() -> str:
    """Build an ES256 JWT valid for 10 minutes (the ceiling is 20)."""
    now = int(time.time())
    payload = {
        "iss": ISSUER_ID,
        "iat": now,
        "exp": now + 600,
        "aud": "appstoreconnect-v1",
    }
    with open(PRIVATE_KEY_PATH) as f:
        return jwt.encode(payload, f.read(), algorithm="ES256", headers={"kid": KEY_ID})
 
 
def latest_build() -> dict | None:
    """Fetch only the most recently uploaded build."""
    res = requests.get(
        "https://api.appstoreconnect.apple.com/v1/builds",
        headers={"Authorization": f"Bearer {make_token()}"},
        params={"filter[app]": APP_ID, "sort": "-uploadedDate", "limit": 1},
        timeout=30,
    )
    res.raise_for_status()
    data = res.json()["data"]
    return data[0]["attributes"] if data else None
 
 
if __name__ == "__main__":
    build = latest_build()
    if build is None:
        print("No build visible in the API yet (it can take a few minutes right after upload)")
        sys.exit(2)
    print(build["version"], build["processingState"], build["uploadedDate"])
    # Exit 0 on VALID, 1 otherwise, so a shell loop can wait on it
    sys.exit(0 if build["processingState"] == "VALID" else 1)

Run it once a minute and your terminal tells you the moment Apple is done:

# Poll every 60 seconds until the build is VALID (Ctrl+C to stop)
until python3 asc_build_state.py; do sleep 60; done

Three things become readable this way. If FAILED or INVALID comes back, validation failed — confirmed, even with no email. If it stays PROCESSING past twenty minutes, walk through causes 1–4 in order. And if the upload succeeded but the build has gone missing from the API list, that is the signature of a duplicate being discarded — bumping the build number and re-uploading is the only way out.

What I wait on is a value, not a screen. Since drawing that line, the hour spent in Processing has become an hour I can spend on something else.

When it still won't budge

If none of the causes above apply, no email arrives, and it has still been processing for over an hour, suspect a genuine delay on Apple's side. Right after a new iOS or Xcode release, builds from around the world stack up and processing really can take hours.

My approach here is simple. First, check Apple's System Status page to confirm "App Store Connect" and "TestFlight" are operating normally. If there's a reported issue, waiting is the only option. If everything is green and it hasn't moved in over three hours, I make a point of not re-uploading the exact same build — it'll be rejected as a duplicate. Bump the build number by one, rebuild cleanly, and upload that. That clears most cases.

What to do next

If you're stuck on Processing right now, start by checking your registered email, then confirm the encryption export compliance declaration (usesNonExemptEncryption: false) is present in your app.json or Info.plist. In my experience, more than half of the Processing stalls with Rork-exported apps come down to that single line.

If you have a spare ten minutes after that, keep asc_build_state.py somewhere handy — it may change how you spend the next hour the status refuses to move. I hope this gives you the shortest way out if you're stuck at the same place.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Dev Tools2026-10-30
It runs in development but the iOS Release build dies on launch — checking whether a missing scheme is the cause
In an expo-router app, an app.json with no scheme can crash only the iOS Release build at launch. Why Debug and Android survive, the two ways to fix it, how to think about leaving the scheme out on purpose, and a pre-submission check.
⬡ Dev Tools2026-10-27
Your EAS Update Opens in Expo Go on iPhone but Stops on Android with "Failed to download remote update". The 403 You Get Even When Signed In
An EAS Update that opens in Expo Go on iOS but stops on Android (SDK 57) with Failed to download remote update. The cause is a sign-in token saved in one place and read from another, and the fix sits on the SDK 58 side. The order to check things in, and what to run yourself.
⬡ Dev Tools2026-10-15
When EXPO_PUBLIC_ Values Read Fine in Dev but Come Back undefined in Production: Telling the Spellings Apart
The API URL reads fine while developing and turns undefined once the app is built. The cause was how process.env was written. I lined up babel-preset-expo's output for dev and production and tabulated which spellings get replaced and which are left behind.