AI-coded apps

    How do I fix Invalid Binary on a Lovable.dev iOS upload?

    App Store Connect build list showing a Lovable.dev Capacitor upload flipped to Invalid Binary after the ingestion audit returned an ITMS-91056 privacy manifest error

    Your Lovable.dev project archived in Xcode, the upload to App Store Connect completed without an Xcode-side error, and a short while later the build status flipped to Invalid Binary with an email naming an ITMS code. The build never reached TestFlight. The question is which check inside Apple's post-upload audit refused the archive, why a Lovable.dev export hits this category of error more often than a native Swift project, and the smallest change that lands the next upload in Processing.

    Short answer

    App Store Connect returns Invalid Binary when its post-upload audit refuses a structural property of the uploaded archive. For a Lovable.dev iOS build the most common cause is a missing or malformed PrivacyInfo.xcprivacy file inside the archive. Lovable.dev exports a static web bundle, the standard path wraps it with Capacitor, and Capacitor plugins call into APIs on Apple's required reason list without declaring them. The fix is to add a valid privacy manifest to the iOS app target, correct any framework signing or Info.plist gaps the email also flags, bump CFBundleVersion, archive again, and re-upload. Apple's Privacy manifest files reference documents the schema the audit applies, and the third-party SDK requirements list names the SDKs that trip the rule.

    What you should know

    • Lovable.dev does not generate a PrivacyInfo.xcprivacy file as part of its iOS export. The Capacitor wrap steps documented in the Lovable to Capacitor guide stop at build, sync, open in Xcode, and never add a privacy manifest.
    • Capacitor plugins like @capacitor/filesystem and @capacitor/preferences call APIs on Apple's required reason list. The official Capacitor privacy manifest documentation names them by example and publishes a sample plist to copy in.
    • The Invalid Binary state lives on the App Store Connect build record, not on the bytes of the IPA. Re-uploading at the same CFBundleVersion leaves the record in place even after the underlying file is corrected.
    • ITMS-91056 covers most Invalid Binary emails on a first Lovable.dev upload. ITMS-91061, ITMS-90683, and ITMS-90755 cover most of the rest.
    • The Xcode Organizer upload and the Transporter app share the same ingestion pipeline. Transporter prints a clearer log, but it cannot rescue a build the validator already refused.

    Why does App Store Connect flag a Lovable.dev build as Invalid Binary?

    App Store Connect runs every uploaded archive through a server-side validator that opens the .app, reads its directory tree, and checks each embedded framework against a schema and a signing register. The validator does not stop at the main target. It reads every PrivacyInfo.xcprivacy in the archive, every binary slice, every nested framework signature, and the top-level Info.plist. A single refused entry flips the status to Invalid Binary and triggers the ingestion email naming an ITMS code.

    A Lovable.dev export hits this audit more often than a hand-written Swift project for one reason: it carries Capacitor and a set of Capacitor plugins, and several of those plugins call APIs Apple's Required Reason API documentation lists as needing a declared reason. When the Lovable.dev workflow generates the Xcode project through npx cap sync and opens it in the IDE, no PrivacyInfo.xcprivacy file is added to the iOS app target. The first archive uploads, the audit reads the absence as a failed declaration, and the build flips to Invalid Binary within minutes.

    The pattern is consistent across the Lovable.dev community. Tutorial write-ups on Lovable.dev plus Capacitor plus Fastlane and forum threads on App Store rejections all stop short of the privacy manifest step. The first signal most developers get is the ingestion email a few minutes after the Xcode upload completes.

    Which ITMS error sits behind your Invalid Binary email?

    The email body names a specific code. For Lovable.dev builds, four codes account for most cases.

    ITMS codeWhat the audit refusedWhat to change
    ITMS-91056A PrivacyInfo.xcprivacy file in the archive does not parse against Apple's schema for the four recognised top-level keys.Replace the file with a valid minimal plist, or update the framework that ships the broken one.
    ITMS-91061A third-party SDK on Apple's published list is missing a signature the audit expects.Pull the signed release of the framework from the maintainer and re-archive.
    ITMS-90683The archive uses a tracked API in code but Info.plist has no matching NSXxxUsageDescription entry.Add the matching usage description string to Info.plist.
    ITMS-90755The binary carries instructions the validator refuses, often from non-standard compiler flags.Audit Build Settings for custom flags and rebuild with the default toolchain.

    Documentation on the Apple Developer Forums thread 791696 covers ITMS-90755 in particular: a DTS engineer points at non-standard compiler flags as the usual cause. Lovable.dev does not change Xcode build settings, so 90755 is rare on a clean export. The codes most Lovable.dev developers see on a first upload are 91056 and 91061, sometimes 90683 when a Capacitor plugin surfaces a hardware permission without a matching Info.plist string.

    How do I add a valid PrivacyInfo.xcprivacy to a Lovable.dev Capacitor project?

    The file lives in the iOS app target alongside Info.plist and ships at the root of the built .app bundle. Three concrete steps land the manifest in a state the audit accepts.

    1. Generate the file inside Xcode. Open the iOS project produced by npx cap sync. Choose File, New, File from Template, scroll to the Resource section, and pick App Privacy File. Name it PrivacyInfo.xcprivacy. Confirm the iOS app target is ticked in the Targets list.
    2. Add the four top-level keys. The plist root takes NSPrivacyTracking (Boolean), NSPrivacyTrackingDomains (array of strings), NSPrivacyCollectedDataTypes (array of dictionaries), and NSPrivacyAccessedAPITypes (array of dictionaries). A minimal valid file sets NSPrivacyTracking to false and the three arrays to empty. Capacitor's sample for @capacitor/filesystem and @capacitor/preferences is a clean starting point.
    3. Confirm the file ends up in the archive. Build the archive, open the Xcode Organizer, right-click the archive, choose Show Package Contents, and verify a PrivacyInfo.xcprivacy file sits at the root of YourApp.app. A file that exists in the project tree but is not added to the Copy Bundle Resources phase never reaches the archive.

    When the project links @capacitor/filesystem or @capacitor/preferences, the NSPrivacyAccessedAPITypes array gains entries for NSPrivacyAccessedAPICategoryFileTimestamp and NSPrivacyAccessedAPICategoryUserDefaults with the right reason codes. When neither plugin is linked, the empty-arrays form is enough. Either way, the file has to validate against the schema; a misspelt category like NSPrivacyAccessedAPICategoryUserDefault (without the trailing s) is a common cause of ITMS-91056 even after the file has been added.

    What signing and build settings on a Lovable.dev export trigger Invalid Binary?

    The default Xcode project that Capacitor opens uses Automatically manage signing. On a first upload that setting is usually fine. The cases where signing causes Invalid Binary on a Lovable.dev export fall into three groups.

    • Mixed signing identities across embedded frameworks. When a Capacitor plugin ships an embedded framework signed by a different developer in an earlier archive, the validator returns an ITMS-91061-style signature error. Pull the framework's latest release and re-resolve dependencies with npx cap sync.
    • Stale bitcode flags on older deployment targets. Apple no longer accepts bitcode submissions. A Capacitor project on an older deployment target that still has bitcode enabled in Build Settings may upload, then fail at audit. Set ENABLE_BITCODE to NO at the project level.
    • App ID team mismatch. A Lovable.dev developer who registered an App ID for one team but signs the archive with a different team in Xcode hits a signature error. App Store Connect ties the binary signature to the App ID team.

    None of these settings is changed by the Lovable.dev export step. They surface inside the Xcode project after npx cap open ios, which is the right place to look first.

    How do I re-upload cleanly after an Invalid Binary?

    The pattern is the same across all four ITMS codes above. Fix the underlying issue, then bump CFBundleVersion. The first action lands the build through the audit. The second action is what App Store Connect actually keys on for the upload record. A re-upload at the same build number returns the same email, even after the underlying file is corrected.

    For builders who want an external automated read of the IPA before the next Xcode upload, PTKD.com (https://ptkd.com) is one of the platforms that inspects compiled archives produced by no-code and vibe-coded workflows and flags PrivacyInfo.xcprivacy issues, missing purpose strings, and SDK signing gaps before App Store Connect runs its own audit. The output names the same ITMS code the ingestion email would, which shortens the loop between an Invalid Binary status and a clean Processing record.

    What to watch out for

    A few patterns turn a one-build fix into a multi-day loop.

    • Editing Info.plist or the privacy manifest in the source tree but not re-archiving. The audit reads the file that ships inside the archive. Always archive a fresh build after the change.
    • Re-uploading at the same CFBundleVersion. App Store Connect keys the Invalid Binary record to the build number.
    • Treating ITMS-91056 as a signing problem. Signing errors sit in the ITMS-91061 range. ITMS-91056 fires on the shape of the privacy manifest file.
    • Assuming the Lovable.dev web preview catches the issue. The Lovable.dev preview is a browser render. The audit that returns Invalid Binary runs on the compiled iOS archive after upload.
    • Patching a vendored Capacitor plugin's manifest without pinning the plugin version. A clean npx cap sync or a fresh npm install overwrites the edit. Pin the plugin version in package.json, or contribute the fix upstream.

    Key takeaways

    • Invalid Binary on a Lovable.dev upload is almost always an ITMS-91056 case, driven by Capacitor plugins calling required reason APIs without a privacy manifest the export never generates.
    • The fix lives inside the Xcode project that npx cap open ios produced, not inside the Lovable.dev web editor.
    • The four top-level keys in PrivacyInfo.xcprivacy are fixed; copy a minimal valid plist from Capacitor's documentation and adjust the API entries to the plugins actually linked.
    • A higher CFBundleVersion is mandatory between any two upload attempts.
    • Some teams outsource the pre-submission audit of compiled IPAs from no-code and vibe-coded workflows to platforms like PTKD.com (https://ptkd.com), which surfaces malformed manifests, missing purpose strings, and SDK signature gaps before App Store Connect rejects the upload.
    • #lovable.dev
    • #invalid binary
    • #capacitor
    • #ios
    • #privacy manifest
    • #itms-91056
    • #app store connect
    • #vibe coding

    Frequently asked questions

    Does Lovable.dev create a PrivacyInfo.xcprivacy file automatically?
    No. The Lovable.dev workflow exports a static web bundle, and the standard Capacitor wrap stops at npx cap sync and npx cap open ios. Neither step adds a privacy manifest to the iOS app target. The developer adds the file manually inside the Xcode project, using File, New, File from Template, App Privacy File. Capacitor's own documentation publishes a sample plist for the common plugin set.
    Why does my Lovable.dev app trigger Apple's privacy manifest rule at all?
    Apple's required reason API rules apply to specific API categories like UserDefaults, FileTimestamp, and SystemBootTime. Several Capacitor plugins call into those categories. When the iOS archive contains those calls and no PrivacyInfo.xcprivacy declares the reason, the audit returns ITMS-91056 or a related declaration error. The rule is independent of how the app was authored. Lovable.dev, FlutterFlow, and a hand-written Capacitor project hit the same audit on upload.
    Can I upload with Transporter instead of Xcode to skip Invalid Binary?
    No. Both Xcode Organizer and the Transporter app submit through the same App Store Connect ingestion pipeline, which runs the same server-side audit on the archive. Transporter prints a clearer error log when the upload fails, which is useful for reading the ITMS code. The Invalid Binary check itself runs on the build after upload regardless of which tool moved the bytes.
    Why did my second upload at the same build number fail again?
    App Store Connect keys the Invalid Binary record to the CFBundleVersion of the archive, not to the bytes of the IPA. A re-upload at the same build number lands on top of the existing record and returns the same email. Increment CFBundleVersion in the iOS app target's Info before archiving the corrected build, and the next upload flows into Processing instead of bouncing back to Invalid Binary.
    Does the Lovable.dev preview catch the Invalid Binary before upload?
    No. The Lovable.dev preview renders the underlying web bundle in a browser. The Invalid Binary state fires on the compiled iOS archive after upload to App Store Connect, which means privacy manifest issues, framework signing gaps, and missing Info.plist purpose strings cannot be observed in the web preview. The first audit signal a Lovable.dev developer sees is the App Store Connect ingestion email after the Xcode upload completes.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free