Cannot upload lower build number after higher build submission is approved

We encountered a weird situation recently. Our daily build process upload an app with a daily incremental 4-digit build number, e.g. 4000, 4001, 4002, etc. Our release build number has a specific requirement to use the date, such as 20240719.

In the past I have learned that in order to upload a new build for the same version number, the new build number needs to be greater than the old one. Thus, if I have uploaded 200.1.0 (20240719), I cannot upload 200.1.0 (4001) anymore, because the daily build's build number is smaller than the release build. I have to expire the 20240719 build in order for the daily build to continue, which is fine.

The problem is, yesterday I submitted 200.1.0 (20240719) for App Store review then got approved. While today's daily build is 200.2.0 (4001) and when it is uploaded, it got rejected for the following error message:

This bundle is invalid. The value for key CFBundleVersion [4001] in the Info.plist file must contain a higher version than that of the previously uploaded version [20240719]. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion With error code STATE_ERROR.VALIDATION_ERROR.90061 for id [redacted] Asset validation failed (-19208)

This befuddles me, because the 20240719 build submitted for review is in an older release version, while the daily build 4001 is using the newer release version number. It seems that TestFlight decided to compare build numbers while ignoring the version numbers?!

Furthermore, after I canceled my approved submission for 200.1.0 (20240719), surprisingly the 200.2.0 (4001) can be uploaded without an error! 😲

It seems that the only factor is whether the build is submitted or not. If an older version number higher build (200.1.0 (20240719)) is not submitted, then TestFlight happily allows newer version number lower build (200.2.0 (4001)) to be uploaded. In contrast, if submitted, then 4001 is not allowed to be uploaded!

Is it an expected behavior? Thank you for the patience.

Today we meet this problem again. The Mac App Store published version 200.5.0 (20240801) causes the daily build 200.6.0 (4318) to fail to upload. Which doesn't make sense in several ways:

  • The version number of the daily build is greater, so the build number shouldn't even be compared!
  • After submission got published, I have expired the TestFlight build for 20240801, so it shouldn't play a role in version comparison at all!
  • Why does an approved and published app build should affect anything in TestFlight?
  • Why iOS TestFlight doesn't have this problem, only MacOS does??

In case someone find this thread with the same problem, I'll try Feedback Assistant and see what Apple says. Likely that we need to adjust our build number pattern to cater them. 🥀

After more reading, I realized the following fact:

  • iOS has different version number strategy than macOS. Specifically, an iOS app's version number typically looks like major.minor.patch (build), whereas for macOS app it looks like major.minor.patch. No build number for macOS app due to historical reasons.
  • On iOS, major.minor.patch = CFBundleShortVersionString, and build = CFBundleVersion
  • on macOS, major.minor.patch = CFBundleVersion

Which causes problem for a cross platform app that used to be iOS only, but recently start to support macOS via Mac Catalyst (exactly our case. =_=!)

The app versioning used to work well with iOS versioning pattern major.minor.patch (build) where the "must contain a higher version" requirement only applies to the build part when the version number is the same. If the version is different, no need to compare build at all.

But on macOS, because there is no build number, it directly compares the major.minor.patch version number, which unfortunately uses the same dict key CFBundleVersion as on iOS. Thus, the single component build number on iOS, becomes the sole number for macOS version comparison.

That doesn't pose a problem if your app's build increases daily. But it causes huge problem if you assign the build manually when you do the App Store upload, like us.

How to solve it? Well, I hope App Store Connect can add some special handling for cross-platform app that originated from iOS, to first compare the version number via CFBundleShortVersionString, so that CFBundleVersion can be treated as a build number to be used for further comparison.

Otherwise, we have to discard the 20-million integers (20240801 to be exact) we've inadvertently wasted for the macOS version number. 😩

Cannot upload lower build number after higher build submission is approved
 
 
Q