---
title: "Troubleshooting"
description: "Fix patches that don't reach devices, warnings and errors from Shorebird patch and release commands, crashes after a patch, and build, sign-in and network failures."
---

This page covers the most common issues with Shorebird Code Push. Still stuck? Reach out on [Discord](https://discord.gg/shorebird) or [file an issue](https://github.com/shorebirdtech/shorebird/issues). The Shorebird team is happy to help.

Find your symptom below, or search the page for the exact message you see.

**A patch didn’t reach devices**

* [Patch not showing up](#patch-not-showing-up)
* [Patches stopped installing on devices](#patches-stopped-installing-on-devices)
* [Patches can’t install because the app isn’t the build Shorebird released](#patches-cant-install-because-the-app-isnt-the-build-shorebird-released)
* [Patch check fails with `Request failed with status: 500`](#patch-check-fails-with-request-failed-with-status-500)
* [Your iOS build number is auto incrementing](#your-ios-build-number-is-auto-incrementing)

**`shorebird patch` warned or stopped**

* [`Your app contains asset changes` warning](#your-app-contains-asset-changes-warning-when-creating-a-patch)
* [`Your app contains native changes` warning](#your-app-contains-native-changes-warning-when-creating-a-patch-even-though-you-havent-changed-swiftobjective-ckotlinjava-code)
* [Patch stops in CI with `Not publishing` (exit code 70)](#patch-stops-in-ci-with-not-publishing-exit-code-70)
* [`shorebird patch` can’t find a release to patch](#shorebird-patch-cant-find-a-release-to-patch)
* [Patching an obfuscated iOS release built with older Flutter](#patching-an-obfuscated-ios-release-built-with-older-flutter)
* [Message saying patch might run slowly](#message-saying-patch-might-run-slowly)
* [Sending a patch-debug.zip to Shorebird](#sending-a-patch-debugzip-to-shorebird)
* [Patch download size is unexpectedly large](#patch-download-size-is-unexpectedly-large)

**A build, release or install failed**

* [`shorebird release` says the release already exists](#shorebird-release-says-the-release-already-exists)
* [`Aborting due to validation errors`](#aborting-due-to-validation-errors)
* [Shorebird fails to install](#shorebird-fails-to-install)
* [Can’t run your app in VS Code](#cant-run-your-app-in-vs-code)
* [Could not find an option named “dart define”](#could-not-find-an-option-named-dart-define)
* [Xcode project `overrides FLUTTER_ build setting(s)` warning](#xcode-project-overrides-flutter_-build-settings-warning)
* [iOS app extension versions don’t match the app](#ios-app-extension-versions-dont-match-the-app)
* [Invalid Podfile file](#invalid-podfile-file)
* [Missing a provisioning profile or no signing team was found](#missing-a-provisioning-profile-or-no-signing-team-was-found)
* [`shorebird preview` can’t install an iOS release](#shorebird-preview-cant-install-an-ios-release)
* [Unsupported class file major version 65](#unsupported-class-file-major-version-65)
* [Android build fails with “lower than Flutter’s minimum supported version”](#android-build-fails-with-lower-than-flutters-minimum-supported-version)
* [`libapp.so.sym or libapp.so.dbg not present` warning on Android](#libappsosym-or-libappsodbg-not-present-warning-on-android)
* [Resolving persistent compile or build failures](#resolving-persistent-compile-or-build-failures)

**The app crashed after a patch**

* [App crashes after a patch installs](#app-crashes-after-a-patch-installs)
* [Deferred components fail to load after a patch installs](#deferred-components-fail-to-load-after-a-patch-installs)

**Sign-in, CI credentials or network**

* [Sign-in and credential errors](#sign-in-and-credential-errors)
* [Shorebird commands fail with network/TLS connection errors behind a proxy](#shorebird-commands-fail-with-networktls-connection-errors-behind-a-proxy)
* [GitHub Actions sign-in errors](/account/trust-rules/#when-a-sign-in-is-refused)

## Patch not showing up

Your first step in debugging should be to check your app’s logs. See [Read device logs](/code-push/device-logs/) for how to get them and what each line means.

You should see logs prefixed with `[shorebird]`. If you do not see `[shorebird]` in your logs, the app you are running was not built using `shorebird release` and cannot receive patches. You will need to redistribute your app using a binary created by `shorebird release`.

If you do see Shorebird in your logs, you’ll want to look for a line that includes the patch check request being made. It looks like:

```
Sending patch check request: app_id: <your app id>, channel: stable, release_version: 1.0.3+16, platform: android, arch: aarch64, current_patch_number: Some(3)
```

`release_version` is the release version your app is running, and `current_patch_number` is the patch it is currently running (`None` if it is running the release unpatched).

Older engines print this line in a different format, for example:

```
Sending patch check request: PatchCheckRequest { app_id: "<your app id>", channel: "stable", release_version: "1.0.3+16", platform: "android", arch: "aarch64", client_id: "<id>", current_patch_number: Some(3) }
```

Depending on the engine version, the older format may leave out `client_id` or `current_patch_number`. It always includes `release_version`.

If the release version is the version you expect to see, check the [Shorebird Console](https://console.shorebird.dev) to ensure that this release exists for the given app ID and that it has a patch. Please reach out on Discord if such a patch exists and is not being applied.

Common issues:

**Patches were installing and then stopped.**

See [Patches stopped installing on devices](#patches-stopped-installing-on-devices).

**The app is running in Debug or Profile mode.**

Shorebird only runs in release builds. Test patches with a build from `shorebird release` or `shorebird preview`, not `flutter run`. See [Does Shorebird work in debug or profile mode?](/code-push/faq/#does-shorebird-work-in-debug-or-profile-mode)

**You are testing on an iOS Simulator.**

iOS patches only install on physical devices; Android emulators work. See [Does Shorebird work on iOS Simulators?](/code-push/faq/#does-shorebird-work-on-ios-simulators)

**The patch was created for a different release version than the one running on your device/emulator.**

Patches are only compatible with the release version they were created for. If you create a patch for version `1.0.0+1`, it will not work on version `1.0.0+2`.

Note

This can happen unexpectedly on iOS due to Xcode’s automatic incrementing of build numbers. If you are seeing this issue on iOS, ensure that the build number of the release and the patch match. See [the iOS releasing guide](/flutter-concepts/releasing-flutter-apps/ios/) for instructions on how to disable automatic build number incrementing.

**How to tell if this is the problem**

You will see `Shorebird updater: no active patch` in your device logs.

**How to fix it**

Ensure that the version of your app on your device/emulator matches the version of the release you patched. You can see what release version your app is running by looking in the device logs for a patch check request:

```
Sending patch check request: app_id: <your app ID>, channel: stable, release_version: 1.0.3+16, platform: android, arch: aarch64, current_patch_number: None
```

Only patches created for this release version will be compatible with your app.

**The app’s process is still running because of a foreground service.**

If the app runs a foreground service or other long-running background work, swiping it from the recent-apps list does not kill the process. Shorebird loads the patch on the next process start.

**How to tell if this is the problem**

The process ID does not change when you swipe the app away. Run `adb shell pidof <your.package.name>` before and after swiping: if it prints the same PID both times, the process never died and no patch will be applied.

From Dart, the equivalent signal is `checkForUpdate()` returning `UpdateStatus.restartRequired`, or `readNextPatch()` reporting a higher patch number than `readCurrentPatch()`.

**How to fix it**

Force-stop the app, or stop the service first, then relaunch. See [How do you use Shorebird with a long-running Android background process?](/code-push/faq/#how-do-you-use-shorebird-with-a-long-running-android-background-process).

## Patches stopped installing on devices

Patches were reaching your users, and now new patches don’t install. Devices keep running the patch they already have. Check these causes in order.

### Your organization reached its patch install limit

Once the apps on your plan have used every patch install the plan allows this billing period, Shorebird refuses patch checks from those apps. New patches stop installing until the limit goes up or the limit resets.

**How to tell if this is the problem**

* The device logs show the patch check failing with:

  ```
  Request failed with status: 403
  ```

* The [Shorebird Console](https://console.shorebird.dev) shows a banner that says “Patches are not being delivered.”, or “Your last payment didn’t go through.” if a payment failed. `shorebird release` and `shorebird patch` (1.6.135 and newer) print a warning that starts with `Patches are not being delivered:`.

* Members of the organization get an email when usage reaches 80% of the limit, and another when it reaches the limit, unless they’ve [turned these emails off](/account/cli/#turn-email-notifications-on-or-off).

**How to fix it**

The banner says which limit was reached. On an Enterprise plan, [email billing](mailto:billing@shorebird.dev) to raise the limit. Otherwise the [organization owner](/account/orgs/#owner) fixes it from the [Plan page](https://console.shorebird.dev/account/plan):

* If the plan’s included installs are used up and the banner says overages are turned off, [turn on overages](/account/billing/#overage-billing) or [upgrade the plan](/account/plans/). Otherwise, upgrade the plan.
* If overages are on and you’ve reached your spending limit (the banner calls it the overage limit), raise the limit.
* If a payment failed, update the payment method. See [Failed payments](/account/plans/#failed-payments).

Devices pick up patches on their next patch check after the upgrade, the limit change, or the plan’s payment going through. After you pay an annual plan’s overage invoice, patches start installing again within the hour. If you change nothing, patches start installing again within the hour after the next billing period starts (for an annual plan’s overage limit, the next month).

### The app in the store isn’t the build Shorebird released

If patches install on some builds but not on the one in the store, see [Patches can’t install because the app isn’t the build Shorebird released](#patches-cant-install-because-the-app-isnt-the-build-shorebird-released).

## Patches can’t install because the app isn’t the build Shorebird released

Every patch is made against the build `shorebird release` uploaded. If the app installed on a device is a different build of the same version, no patch to that release can install on it.

**How to tell if this is the problem**

The device logs show a patch failing with a message like:

```
This app reports version 1.0.7+8, but the binary is different from the version 1.0.7+8 that was submitted to Shorebird.
```

**Common causes**

* The build in the store was made with Shorebird’s Flutter some other way than `shorebird release`, such as archiving in Xcode or running Gradle after `shorebird release` ran, which leaves the project set to use Shorebird’s Flutter. A build made with the standard Flutter’s `flutter build` doesn’t include Shorebird, so it never reports this.
* `shorebird release` ran again for the same version, after an earlier run stopped partway or after the release was deleted, and the build from the earlier run was published. Shorebird keeps only the build from the last run.
* On iOS, the archive was uploaded with Xcode’s **Distribute App** flow with **Manage Version and Build Number** checked. Xcode then rewrites the build number in the uploaded app, so the build in the store doesn’t match the one Shorebird recorded for the release. Uncheck it when you upload; see [Uploading from Xcode](/code-push/release/#uploading-from-xcode). An ExportOptions.plist can do the same; see [Your iOS build number is auto incrementing](#your-ios-build-number-is-auto-incrementing).

**How to fix it**

Publish the build `shorebird release` made, or release a new version with `shorebird release` and publish that build. Patches made for the new version install on devices that update to it.

If only a few devices report this, they may be running a modified copy of your app, and no change is needed.

## Patch check fails with `Request failed with status: 500`

The device logs show the patch check failing with:

```
Request failed with status: 500
```

If your app calls `update()` from [package:shorebird\_code\_push](https://pub.dev/packages/shorebird_code_push), it throws an `UpdateException` with the same message.

A 500 status means Shorebird’s server failed to answer the patch check. It isn’t caused by your app or your patch, and there is nothing to change in either. Devices keep running the code they already have, whether that’s the release or an earlier patch, and check again on their next launch, or the next time your app calls `update()`. Once the server answers again, they download the latest patch as usual.

If patch checks keep failing, reach out on [Discord](https://discord.gg/shorebird) or at <contact@shorebird.dev> with your app ID and the release version from the log.

## App crashes after a patch installs

Your iOS app runs fine as released, but once a patch installs it crashes at launch or soon after. If the release was built with Flutter 3.44 before 3.44.9 at revision `0cae2fc0a4`, including an early 3.44.9 build at revision `c2515c46c7`, the crash is in that Flutter version, and no patch can fix it. Roll back every iOS patch on the release, then publish a new store release built with a newer Flutter.

**How to tell if this is the problem**

* The crash happens only on iOS, starts after a patch installs, and stops once every patch on the release is rolled back.

* Crash reports from Xcode or Crashlytics show one of these:

  * `InstructionsTable::SetCodeAt`, while the patch loads at startup, before any of your Dart code runs.
  * `SimpleHashMap::Lookup` with `DRT_SwitchableCallMiss` further down, when execution returns into patched code, most often where an `await` resumes.

  The crash can also show up as an abort where a failed null check would normally throw a Dart error.

* The release was built with an affected Flutter revision. Check the revision, not only the version, with `shorebird releases info`:

  ```
  shorebird releases info --release-version 1.0.0+1
  ```

  ```
  Flutter:    3.44.8
  Revision:   c15ef6379403a0a55531a058bdb2c8e55bc05c98
  ```

  In the [Shorebird Console](https://console.shorebird.dev), the release’s page shows the version and the first 10 characters of the revision under the release’s name, and a “Known crashes on iOS.” alert on an affected release. The release list also shows an error sign next to each affected release.

A crash with the `InstructionsTable::SetCodeAt` signature has also been reported on 3.44.9 at `0cae2fc0a4`, and didn’t happen with the same app on Flutter 3.47. If you see it there, publish a new release with the Flutter version the current Shorebird ships.

Shorebird 1.6.135 and newer warn when you patch an affected iOS release. The warning starts with:

```
[WARN] Release 1.0.0+1 was built with Flutter 3.44.8 (c15ef63794), which has a known problem on iOS: Known crashes on iOS.
```

and, after a description of the crashes, ends with:

```
A patch cannot change the Flutter version a release was built with. To fix this, create a new release with a Flutter version without this problem.
```

The patch is still created.

**How to fix it**

1. [Roll back](/code-push/rollback/) every patch on the affected iOS release. Rolling back only the newest patch moves devices to the previous patch, which can crash the same way.
2. Run `shorebird upgrade`, then publish a new store release. By default, `shorebird release` builds with the Flutter version the installed Shorebird ships, so an older Shorebird can build on an affected revision again. If you pass `--flutter-version` (including `fvm` or `system`), update that too. Before submitting to the store, check with `shorebird releases info` that the new release isn’t on an affected revision.
3. Patch the new release. Until users update from the store, a patch to the old iOS release can crash their app.

**Why a better patch can’t fix it**

A patch replaces your Dart code, but it runs on the Flutter engine inside the store build, and Shorebird builds every patch with the Flutter version its release was built with. The crash is in that engine, so only a new release built with a fixed Flutter version removes it.

Not every crash after a patch is this one. If the app still crashes with every patch rolled back, the crash is in the release, not the patch. If it crashes only with a patch installed and the release isn’t on an affected revision, reach out with the crash report and the [patch-debug.zip](#sending-a-patch-debugzip-to-shorebird) from that `shorebird patch` run.

## Deferred components fail to load after a patch installs

Your Android app uses Flutter [deferred components](https://docs.flutter.dev/perf/deferred-components). They load as released, but once a patch installs, every `loadLibrary()` call for a deferred component throws:

```
DeferredLoadException: 'Deferred loading unit is from a different program than the main loading unit'
```

This happens with any patch, even one that changes no code in the deferred component.

Shorebird doesn’t support deferred components. A patch replaces your app’s whole compiled Dart program, while each deferred component was compiled with the release, so the Dart VM refuses to load it alongside the patch.

**How to fix it**

1. [Roll back](/code-push/rollback/) every patch on the affected release. Only the release itself can load its deferred components, so rolling back only the newest patch moves devices to the previous patch, which fails the same way.
2. Move the code out of deferred components and publish a new store release, then patch that release. When most of a feature’s size is in assets such as models or media, download those at runtime or with [Play Asset Delivery](https://developer.android.com/guide/playcore/asset-delivery) instead, which works with Shorebird.

## `Your app contains asset changes` warning when creating a patch

The `shorebird patch` command will print a warning if it detects changes to files in your compiled app that correspond to asset changes (e.g., added or removed images, fonts, etc.). This does not always mean that your patch will not work, but Shorebird cannot be sure that the changes are safe. A patch can’t change assets, so an asset change reaches devices only in a new release.

An example of this warning:

```
✓ Verifying patch can be applied to release (4.0s)
[WARN] Your app contains asset changes, which will not be included in the patch.
    Added files:
        base/assets/flutter_assets/assets/images/bg_button_disable.png
    Changed files:
        base/assets/flutter_assets/AssetManifest.bin
        base/assets/flutter_assets/AssetManifest.json
        base/assets/flutter_assets/fonts/MaterialIcons-Regular.otf
Continue anyway? (y/N)
```

So what does this mean? In this case, it means you added a new image to your app. The warning is because your patched Dart code could *depend* on those new assets which will not be present when the patch is applied in the wild. It can be safe to ignore this kind of warning if you’re removing an asset that is not used by your code, or your Dart code knows how to handle the asset being missing.

Also included in the above changes are the `AssetManifest` files. These files change any time you add or remove an asset from your app, and are generally a symptom rather than the cause of the warning.

The final file changed above is the `MaterialIcons-Regular.otf` font file, which can happen if your app uses more or fewer icons from the Dart code. Flutter will automatically “tree shake” your fonts, so if you don’t use an icon in your Dart code, it will not be included in the final app. You can disable this behavior with `--no-tree-shake-icons` at the risk of increasing your app size.

Changes to your app’s native code, such as `.dex` files on Android, are not patchable by Shorebird and get a separate warning, covered [below](#your-app-contains-native-changes-warning-when-creating-a-patch-even-though-you-havent-changed-swiftobjective-ckotlinjava-code).

**What happens if you ignore this warning?**

You can bypass this warning by passing the `--allow-asset-diffs` flag to the `shorebird patch` command.

The consequences of ignoring this warning depend on the changes that were made. In the tree-shaking example above, if you ignore the warning, your app will render incorrectly if you use an icon that was not included in the release build. Any assets introduced in a patch will fail to load, and your app may crash if it depends on them.

If you are not sure whether your change is safe, you can [stage your patch](/code-push/guides/staging-patches) and test locally before deploying it to users. For which files count as assets, and ways to keep content changeable between store releases, see [Assets in Flutter apps](/flutter-concepts/assets/).

## `Your app contains native changes` warning when creating a patch, even though you haven’t changed Swift/Objective-C/Kotlin/Java code

The `shorebird patch` command prints a warning if it detects changes in your compiled app that correspond to native code changes. This does not always mean that your patch will not work, but because Shorebird cannot be sure that the changes are safe, and because Shorebird can’t patch non-Dart code, it prints a warning.

What the CLI compares depends on the platform:

* **Android** (`shorebird patch android`): the `.dex` files in your app. The warning reads `Your app contains native changes, which cannot be applied with a patch.`

* **iOS and macOS** (`shorebird patch ios`, `shorebird patch macos`): Xcode builds aren’t byte-for-byte repeatable, so a difference in your app’s executable doesn’t produce a warning on its own. When the executable differs from the release’s, the CLI also compares your `ios/Podfile.lock` (or `macos/Podfile.lock`) with the one used to build the release, and warns if they differ:

  ```
  Your ios/Podfile.lock is different from the one used to build the release.
  This may indicate that the patch contains native changes, which cannot be applied with a patch. Proceeding may result in unexpected behavior or crashes.
  ```

  The comparison is of the whole file, so once the executable differs, anything that changes Podfile.lock triggers the warning: `pod update`, a plugin version change, an edit to your `Podfile`, or a different CocoaPods version (Podfile.lock records it). Native changes that don’t touch Podfile.lock, such as edits to your own Swift or Objective-C code or to Swift Package Manager dependencies, produce no warning, and neither does anything when the release was built without a Podfile.lock. Check those yourself before patching.

  The release stores only a hash of its Podfile.lock, not the file, so the warning can’t show what changed. To see the difference, diff your `ios/Podfile.lock` (or `macos/Podfile.lock`) against the one in the commit you built the release from, for example `git diff <release-commit> -- ios/Podfile.lock`. If that shows no difference, the release was built with a Podfile.lock that was never committed, for example one regenerated by `pod install` in CI.

Windows, Linux, `shorebird patch aar` and `shorebird patch ios-framework` patches don’t check for native changes, so this warning doesn’t appear there.

Note

On Android, Shorebird assumes a repeatable build — if you build the application twice it ends up byte-for-byte identical. Some Flutter Plugins or obfuscation solutions violate this assumption and can cause these native changes to appear. Shorebird may be incompatible with those plugins. You can test for this by doing a `shorebird release` and then `shorebird patch` with no changes and seeing if you still get a native changes warning. If you believe this is the case, please reach out; the Shorebird team is happy to help.

This can be caused by a number of things. The most common causes are:

1. A dependency/plugin you are using has changed its native code. **You should use caution when publishing patches that include changes to native code from plugins. In the worst case, these changes may cause your patched app to crash.**

   Tip

   Add your `pubspec.lock` file to version control so you’re always aware of updates to your dependencies.

   Versioning your `pubspec.lock` file ensures changes to transitive dependencies are explicit. Each time the dependencies change due to `dart pub upgrade` or a change in `pubspec.yaml`, the difference will be apparent in the lock file.

2. (Android) A dependency/plugin produces a different output on every build. This can happen if the dependency includes a timestamp indicating when it was built, for example. This kind of change is usually safe to publish, but you should be sure this is the only reason you are seeing this warning.

3. The version and build number of the patch do not match that of the release. For example, if the release was built with version `1.0.0+1`, but the patch was generated with version `1.0.0+2`, you might see this warning. Shorebird has implemented some safeguards to make this less likely, but it is worth verifying if you are seeing this warning and you do not know why.

**What happens if you ignore this warning?**

Danger

If the changes are to native code that interacts with your Flutter app or with Flutter itself, **your app will crash**.

If the native code that changed does not interact with your Dart code or Flutter at all, the patch should run without issue.

If you are not sure whether your change is safe, you can [stage your patch](/code-push/guides/staging-patches) and test locally before deploying it to users.

On Android, when Java or Kotlin code changed, the warning also names the classes, methods, and fields that each changed method’s differing instructions reference, which usually points at the dependency that changed. It details up to 10 methods per DEX file. To print every changed method and instruction in full, including string constants, pass `--show-dex-diff` to `shorebird patch`. This needs Shorebird 1.6.130 or newer.

If you are sure the changes are safe, you can bypass this warning by passing the `--allow-native-diffs` flag to the `shorebird patch` command.

## Patch stops in CI with `Not publishing` (exit code 70)

Your `shorebird patch` job in CI failed with exit code 70 and an error like this. When only one kind of change is blocked, the first line starts `Not publishing: native code changed` or `Not publishing: assets changed`, and the hint names only that flag:

```
Not publishing: native code and assets changed since the release, and a patch can't include those changes.
To ship these changes, create a new release. Run: shorebird release android
To publish the patch without them, pass --allow-native-diffs --allow-asset-diffs.
Only do this if your Dart code doesn't depend on the native changes: a mismatch between your Dart code and the release's native code can crash your app.
```

The patch build differs from the release in a way a patch can’t carry. On your own machine, `shorebird patch` asks `Continue anyway?`. In CI there’s nobody to answer, so the patch stops instead. The CLI treats a run as CI when stdin or stdout isn’t a terminal, when it detects a CI environment variable such as `CI` or `GITHUB_ACTIONS`, or when you pass `--json`. With `--json`, the same message and hint are in the error envelope’s `message` and `hint`.

Above that error, the log says what changed:

* `Your app contains native changes, which cannot be applied with a patch.`, followed by the changed native files (not printed by `shorebird patch ios` or `shorebird patch macos`; see below). See [the native changes warning](/code-push/troubleshooting#your-app-contains-native-changes-warning-when-creating-a-patch-even-though-you-havent-changed-swiftobjective-ckotlinjava-code) for common causes.
* `Your app contains asset changes, which will not be included in the patch.`, followed by the changed asset files. See [the asset changes warning](/code-push/troubleshooting#your-app-contains-asset-changes-warning-when-creating-a-patch).
* With `shorebird patch ios` or `shorebird patch macos`, `Your ios/Podfile.lock is different from the one used to build the release.` (or `macos/Podfile.lock`).

Shorebird 1.6.135 and newer print these as errors. Older versions print them as warnings, end with `Not publishing.` (`Exiting.` in older releases), and exit with the same code. They stop at the first kind of change, so a build with both native and asset changes stops again on the assets after you pass `--allow-native-diffs`. The flags are the same in every version.

**Decide which way to ship the change:**

* **The Dart code needs the change** (a new plugin, a changed native API, a new asset): ship it in a new store release. The error prints the command, such as `shorebird release android`.
* **The Dart code doesn’t depend on it** (an unused asset removed, a dependency that rebuilt with the same behavior): pass the flag the error names, `--allow-native-diffs`, `--allow-asset-diffs` or both, to publish the patch without the change. Devices keep the release’s native code and assets.

If you’re not sure, publish to a [staging track](/code-push/guides/staging-patches) first and test it.

**On Android**, the log also lists the dependencies whose versions differ from the release, under `Dependency versions differ from the release:`. A dependency that resolved to a newer version for the patch build is a common cause of `.dex` changes you didn’t make. Pin dependency versions, or turn on [Gradle dependency locking](https://docs.gradle.org/current/userguide/dependency_locking.html), so the patch build resolves the same versions as the release.

**With `shorebird patch ios` and `shorebird patch macos`**, Xcode builds aren’t byte-for-byte repeatable, so changed native files alone don’t stop the patch. For native code, the CLI only stops it when `Podfile.lock` differs from the release’s. Asset changes still stop it, and are checked first: if both changed, the patch stops on the assets, then on `Podfile.lock` after you pass `--allow-asset-diffs`. Check out the `Podfile.lock` the release was built with, or release again.

A patch for a release signed with your own key stops with exit code 64 if you don’t pass the keys (Shorebird 1.6.135 and newer). This happens in CI and locally. See [Patch signing](/code-push/guides/patch-signing) for the flags.

## `shorebird patch` can’t find a release to patch

A patch applies to one release, on one platform. `shorebird patch` stops when there’s no finished release for it to apply to. Each message below is followed by the command to run.

**The release version doesn’t exist**

```
Release not found: "1.0.0+1".
Run `shorebird releases list --app-id <app-id>` to see its releases.
```

`shorebird patch` stops with exit code 70 when no release matches `--release-version`, or the version it read from the build. Check the version for a typo, and with flavors, pass the same `--flavor` you released with: each flavor has its own app ID. If that version was never released, release it, or patch a version that was.

**No release on this platform**

```
No iOS releases found for app <app-id>.
A patch needs a release to apply to (if this is the wrong app, check app_id in shorebird.yaml or pass --flavor). Run: shorebird release ios
```

Either the app has no release on this platform yet, or the patch is looking in the wrong app. With flavors, each flavor has its own app ID in `shorebird.yaml`, and a patch without `--flavor` uses the default `app_id`. Pass the same `--flavor` you released with. If the app really has no release, create one with `shorebird release` and publish that build to the store.

**The release version exists, but not on this platform**

```
Release 1.0.0+1 has no iOS build.
Run: shorebird release ios
```

The version was released on another platform only, for example Android. Run `shorebird release` for this platform with the same version to add it to the release, and publish that build.

**The release didn’t finish**

```
Release 1.0.0+1 is incomplete: the release command that created it was stopped or failed.
Re-run the release for this version, or create a new one. Run: shorebird release ios
```

A `shorebird release` run for this version stopped before it finished, so the release has no build to patch. Run `shorebird release` again for the same version and publish the build from that run, or release a new version. Don’t publish a build from the run that stopped: patches won’t install on it (see [Patches can’t install because the app isn’t the build Shorebird released](#patches-cant-install-because-the-app-isnt-the-build-shorebird-released)).

If you deleted the release or the app, see [If you deleted an app or release by mistake](/code-push/delete/#if-you-deleted-an-app-or-release-by-mistake).

## Patching an obfuscated iOS release built with older Flutter

`shorebird patch ios` stops with exit code 69 and an error like this:

```
Release 1.0.0+1 was built with obfuscation on Flutter 3.38.5, but patching an obfuscated iOS release requires Flutter 3.41.2 or later.
Create a new release to patch. Run: shorebird release ios --obfuscate --flutter-version=3.41.2
```

An iOS patch is linked against its release, so it has to reuse the release’s obfuscated names, and Flutter older than 3.41.2 can’t do that. A patch is always built with its release’s Flutter version, so this release can’t be patched. Create a new release with `--obfuscate` on Flutter 3.41.2 or newer, publish it to the App Store, and patch that release. The Flutter version the current Shorebird ships by default works too, so you can leave out `--flutter-version`.

The same applies to `shorebird patch ios-framework`. On other platforms, these releases can still be patched, but each patch is obfuscated independently and can be larger; see [Patch download size is unexpectedly large](#patch-download-size-is-unexpectedly-large).

## `shorebird release` says the release already exists

`shorebird release` stops with exit code 70 and:

```
It looks like you have an existing android release for version 1.0.0+1.
Please bump your version number and try again.
```

That version is already released on this platform, and a version can be released only once per platform. Increase the build number (or the version) in `pubspec.yaml`, or pass `--build-number`, and run `shorebird release` again. See [Release versions](/code-push/release/#release-versions).

If you meant to ship a change to that release, run `shorebird patch` instead.

## `Aborting due to validation errors`

Before building, `shorebird release` and `shorebird patch` check your project. When a check finds an error, they print it and stop with `Aborting due to validation errors.` Run `shorebird doctor` in your project to see every check and its result. When some issues can be fixed for you, the output ends with:

```
1 issue can be fixed automatically with shorebird doctor --fix.
```

Run `shorebird doctor --fix` to apply those fixes, then commit the changed files. The errors are:

* `android/app/src/main/AndroidManifest.xml is missing the INTERNET permission.` Patches can’t download without it. `--fix` adds it.
* `...removes the INTERNET permission with tools:node="remove", but Shorebird needs it to download patches.` Remove that `<uses-permission>` entry from the manifest. `--fix` doesn’t change it.
* `...Release.entitlements is missing the Outgoing Connections (com.apple.security.network.client) entitlement.`, or the `Allow Unsigned Executable Memory` entitlement. A macOS app needs both to download and run patches. `--fix` adds them.

`shorebird doctor` also prints these warnings, which don’t stop a release or a patch:

* `pubspec.lock is not tracked in source control.` Commit your lock files, so a patch builds with the same dependency versions as its release.
* [Xcode project `overrides FLUTTER_ build setting(s)` warning](#xcode-project-overrides-flutter_-build-settings-warning).
* [`libapp.so.sym or libapp.so.dbg not present` warning on Android](#libappsosym-or-libappsodbg-not-present-warning-on-android), which `shorebird doctor` reports as a legacy `keepDebugSymbols` line.
* ``A new version of shorebird is available! Run `shorebird upgrade` to upgrade.``

Some project problems stop a command with their own message instead:

* A missing `shorebird.yaml`:

  ```
  Unable to find shorebird.yaml. Are you in a shorebird app directory?
  ```

  Run the command from your app’s root directory, or run `shorebird init` if the app isn’t set up yet.

* `shorebird.yaml` not listed as an asset:

  ```
  Your pubspec.yaml does not have shorebird.yaml as a flutter asset.
  ```

  Add it under `assets` in the `flutter` section of `pubspec.yaml`, or run `shorebird doctor --fix`, which adds it.

* `The iOS project has no Xcode scheme for flavor "staging"`. Add the scheme, or pass a flavor that has one. See the [flavors guide](/code-push/guides/flavors/#ios-and-macos).

* `The project has flavors ..., but no --flavor argument was provided.` is a warning: the command goes on with the default `app_id`. Pass `--flavor` to release or patch a flavor.

## Shorebird fails to install

This can happen on Windows due to Windows’ limit of 260 characters for a path (`MAX_PATH`). The same limit can also stop a build.

**Shorebird 1.6.133 and older** clone Flutter without long path support, so the clone can fail. Upgrade Shorebird, or run:

```
git config --system core.longpaths true
```

You may need to run this as an administrator, and you will need to restart your terminal after running this command. Shorebird 1.6.134 and newer enable long paths in their own Flutter clone and don’t need this.

**Flutter 3.47.9 and newer** (the default in Shorebird 1.6.135 and newer) stop with an error when a path in your build exceeds the limit:

```
The filename or extension is too long.
...
Please consider moving the Flutter SDK and/or project to a shorter path, or enabling long paths on Windows.
```

Move your project to a shorter path (for example `C:\src\my_app`), or [enable long paths in Windows](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation#enable-long-paths-in-windows-10-version-1607-and-later).

## Can’t run your app in VS Code

If you see error output like the following when using the Run or Debug button in VS Code:

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Could not find io.flutter:arm64_v8a_debug:1.0.0-4a5e8142f3e7368a48e4f6151cb7b1a684d6dd83.
     Searched in the following locations:
```

VS Code is probably using Shorebird’s version of Flutter instead of the Flutter on your path. Shorebird builds resolve your project’s packages with Shorebird’s Flutter, which records that Flutter in `.dart_tool/package_config.json`. The Dart-Code extension older than v3.140 prefers that file over your `PATH`, so it switches to Shorebird’s Flutter after a Shorebird build.

To fix it, do one of these:

* Update the Dart extension in VS Code to v3.140 or newer, which prefers the Flutter on your `PATH`.

* Run `flutter pub get` with your own Flutter after a Shorebird build. This rewrites `package_config.json` to point at your Flutter.

* Explicitly provide VS Code with the path to your Flutter installation. In your `settings.json` file, add the line:

  ```
  "dart.flutterSdkPath": "/path/to/flutter"
  ```

  Where “/path/to/flutter” is the path to your Flutter installation. You can get this by running `which flutter` in your terminal (or `where.exe flutter` on Windows) and removing the `/bin/flutter` from the end of that path.

Shorebird 1.6.135 and older ran `flutter pub get` with the Flutter on your `PATH` after every build to keep VS Code on your Flutter. That step could also make Xcode’s Product > Archive fail after `shorebird release`. Shorebird 1.6.136 and newer no longer run it, so upgrade if you see that.

## Could not find an option named “dart define”

In PowerShell, Shorebird 1.6.131 and older drop the `--` separator (see [this StackOverflow answer](https://stackoverflow.com/a/15788023)), so the `flutter build` arguments after it fail with `Could not find an option named`. Run `shorebird upgrade`, or quote the separator:

```
shorebird release android '--' --no-tree-shake-icons
```

`--dart-define` and `--dart-define-from-file` don’t need the separator.

## Xcode project `overrides FLUTTER_ build setting(s)` warning

`shorebird doctor` and `shorebird init`, and `shorebird release` and `shorebird patch` for iOS, print this warning when your Xcode project hard-codes a Flutter build setting:

```
ios/Runner.xcodeproj/project.pbxproj overrides FLUTTER_ build setting(s): FLUTTER_ROOT. FLUTTER_* variables are set by Flutter (at runtime or via ios/Flutter/Generated.xcconfig) and should not be hard-coded in the Xcode project.
```

Flutter sets `FLUTTER_*` build settings itself, in `ios/Flutter/Generated.xcconfig`. A value hard-coded in the Xcode project takes priority over that file. For example, a `FLUTTER_ROOT` that points at your own Flutter install can make Xcode build part of your app with a different Flutter than Shorebird’s, which can cause build failures. When the two installs are on different Dart versions, the Xcode archive can fail with:

```
Can't load Kernel binary: Invalid kernel binary format version.
```

That message means a Dart tool read a file compiled by a different Dart version. A hard-coded `FLUTTER_ROOT` is one cause. Another, which happens without this warning, is a build phase that runs a globally activated Dart package, such as `flutterfire_cli` uploading Crashlytics symbols: the package was compiled by the Dart that activated it, and the build runs it with another. The lines after the error then name the package, for example:

```
flutterfire_cli as globally activated doesn't support Dart 3.6.0.
```

To fix the warning, remove each setting it names:

1. Open `ios/Runner.xcworkspace` in Xcode.
2. Select the **Runner** project, then the **Build Settings** tab.
3. Search for `FLUTTER_`.
4. Select each setting the warning lists and press **Delete**. Check every target and build configuration.

If the warning named `FLUTTER_ROOT`, removing it also fixes the kernel binary error. If the error appears without the warning, as with a globally activated package, release at the Flutter version you already use (Shorebird 1.6.123 or newer): `--flutter-version=fvm` if you manage Flutter with [fvm](https://fvm.app), or `--flutter-version=system` for the `flutter` on your `PATH`. Shorebird still builds with its own Flutter, but at that version, so both use the same Dart. See [Match the Flutter version you already use](/getting-started/flutter-version#match-the-flutter-version-you-already-use).

`FLUTTER_TARGET` is allowed and never triggers the warning, since projects commonly set it to a flavor’s entry point, such as `lib/main_dev.dart`.

For a Flutter module used with add-to-app, the check looks at `.ios/Runner.xcodeproj` instead.

## Your iOS build number is auto incrementing

Your iOS build number changes between `shorebird release` and the build that reaches App Store Connect, so patches don’t install. A common cause is an ExportOptions.plist that sets `manageAppVersionAndBuildNumber` to true, which makes Xcode rewrite the build number on export. Shorebird needs you to control your app’s version and build number, since a patch targets one release version.

When you pass that plist with `--export-options-plist`, `shorebird release ios` and `shorebird patch ios` catch it before building and stop with:

```
Exported options plist ios/ExportOptions.plist sets "manageAppVersionAndBuildNumber" to true.
```

To fix it, set `manageAppVersionAndBuildNumber` to false in your ExportOptions.plist:

```
<key>manageAppVersionAndBuildNumber</key>
<false/>
```

The CLI’s message also suggests removing the key, but set it to false instead: when the export uploads to App Store Connect, Xcode treats a missing `manageAppVersionAndBuildNumber` as true.

## iOS app extension versions don’t match the app

Shorebird 1.6.125 and newer print this warning from `shorebird release ios` when an app extension, such as a notification service extension, has a different version or build number from your app, which App Store Connect rejects (ITMS-90473):

```
These app extensions have versions that do not match the app:
```

Shorebird builds with Xcode’s “Manage Version and Build Number” off, so Xcode doesn’t update extension versions for you. The warning lists each extension’s values next to the app’s.

The release that printed the warning is already created, and `shorebird release` refuses the same version again. To fix it:

1. Bump your app’s build number in `pubspec.yaml`.
2. In Xcode, set each extension target’s `MARKETING_VERSION` and `CURRENT_PROJECT_VERSION` build settings to the app’s new version and build number.
3. Run `shorebird release ios` again.

Update the extensions’ versions together with the app’s on every release.

## Invalid Podfile file

You might see this error message if the `FLUTTER_ROOT` definition in your project’s `ios/Flutter/Generated.xcconfig` points to a Shorebird Flutter installation. This can be fixed by running any of:

1. `flutter clean`, or
2. `flutter build ios` in your project’s root directory, or
3. `flutter run` in your project’s root directory and targeting an iOS simulator/device.

## Unsupported class file major version 65

The error `Unsupported class file major version 65` (or 66—the number varies sometimes) happens when gradle is being executed with an incompatible Java version.

You can check the specific Gradle version that your app is using by running `shorebird doctor -v` inside the project folder. This command will also print the Java version that Shorebird is using.

Refer to the [official Gradle documentation](https://docs.gradle.org/current/userguide/compatibility.html) to check which Java version works with which Gradle release.

Shorebird looks for Java in this order, and uses the first one it finds:

1. The `jdk-dir` Flutter setting, if you’ve set one.
2. The JDK bundled with Android Studio.
3. The `JAVA_HOME` environment variable.
4. The `java` on your `PATH`.

`shorebird doctor -v` prints the Java path it picked. Because Android Studio’s JDK comes before `JAVA_HOME`, setting `JAVA_HOME` has no effect on a machine with Android Studio installed. To use a different JDK there, set `jdk-dir`:

```
shorebird flutter config --jdk-dir=/path/to/jdk
```

`shorebird flutter config` passes its arguments to Shorebird’s copy of `flutter config`. Flutter stores `jdk-dir` in your user settings, not in the SDK, so it also changes the JDK used by any other Flutter install on your account. To go back to automatic detection, run `shorebird flutter config --jdk-dir=`.

* [Android Studio](https://developer.android.com/studio) comes with a bundled JDK which should be auto-detected by Shorebird and might be the easiest way of solving the issue.
* If in a GitHub Action, the [setup-java](https://github.com/actions/setup-java) action can help.
* Or install the required Java version for your project’s Gradle release and point `jdk-dir` at it, or `JAVA_HOME` if Android Studio isn’t installed.

## Android build fails with “lower than Flutter’s minimum supported version”

Starting with Flutter 3.47, Android builds fail if your project uses a Gradle, Android Gradle Plugin (AGP), or Kotlin version older than Flutter’s minimum:

| Dependency            | Minimum version |
| --------------------- | --------------- |
| Gradle                | 8.14            |
| Android Gradle Plugin | 8.11.1          |
| Kotlin                | 2.2.20          |

Earlier Flutter versions only printed a warning for these versions. Java 17 remains the minimum Java version, unchanged. The error names the dependency that is too old:

```
Error: Your project's Gradle version (8.12.0) is lower than Flutter's minimum supported version of 8.14.0. Please upgrade your Gradle version.
Alternatively, use the flag "--android-skip-build-dependency-validation" to bypass this check.
```

The error also includes a “Potential fix” line pointing at the file to change. Gradle is set in `android/gradle/wrapper/gradle-wrapper.properties`. AGP and Kotlin are set in the `plugins` block of `android/settings.gradle` (or `settings.gradle.kts`). Projects created from older templates set them in the top-level `android/build.gradle` instead.

If you need to ship before upgrading, you can skip the check temporarily by passing Flutter’s flag:

```
shorebird release android --android-skip-build-dependency-validation
```

Pass the same flag to `shorebird patch android`. Treat this as a stopgap: Flutter doesn’t support building with these older versions.

## `libapp.so.sym or libapp.so.dbg not present` warning on Android

Starting with Flutter 3.44, the Android Gradle Plugin strips `libapp.so` and produces a `libapp.so.sym` file, which Google Play Console uses to symbolicate Dart crashes. If you see this warning when building an Android release:

```
libapp.so.sym or libapp.so.dbg not present when checking final appbundle for debug symbols. Play Console will not receive Dart crash symbols for this build. To enable, remove `packaging.jniLibs.keepDebugSymbols.add("**/libapp.so")` from android/app/build.gradle.kts.
```

your `android/app/build.gradle` (or `build.gradle.kts`) most likely still contains this line, which some projects added to keep `libapp.so` unchanged for Shorebird:

```
packaging.jniLibs.keepDebugSymbols.add("**/libapp.so")
```

On Flutter 3.44 and newer, remove it. The line stops the Android Gradle Plugin from stripping `libapp.so`, so no `libapp.so.sym` is produced. Your build still succeeds, but Play Console won’t be able to symbolicate Dart crashes. `shorebird doctor` warns you if the line is present.

On Flutter versions older than 3.44, keep the line.

The advice above applies to Flutter apps. If you [add Flutter to an existing Android app](/code-push/guides/add-to-app/android), keep the line in your host app’s `app/build.gradle` on every Flutter version.

## Missing a provisioning profile or no signing team was found

This issue is addressed in the [releasing guide](/code-push/release). Take a look at the iOS section for more information.

## `shorebird preview` can’t install an iOS release

If `shorebird preview` fails to install an iOS release with an error about the provisioning profile, the release’s archive was signed with a profile the device doesn’t accept. An App Store distribution profile never installs on a device, and a development or ad hoc profile only installs on the devices it includes. See [iOS signing](/code-push/preview/#ios-signing) for how to sign a release that you can both preview and upload to the App Store.

## Message saying patch might run slowly

If `shorebird patch` warned that it was only able to share part of your Dart code with the released app, or refused to publish because the link percentage is below the minimum threshold, see [Link percentage and slow patches](/code-push/performance/#link-percentage-and-slow-patches).

***

## Sending a patch-debug.zip to Shorebird

`shorebird patch ios` writes `build/patch-debug.zip` when it [links](/code-push/system-architecture#how-shorebird-code-push-works) the patch against its release. Send it with any report of a slow patch or a low shared-code percentage.

### When it is produced

Every `shorebird patch ios` run writes one. Android patches do not use the linker and do not produce one.

Shorebird names it in the patch summary only when the link percentage is below 90%:

```
🔍 Debug Info: /path/to/your_app/build/patch-debug.zip
```

Even if you did not see that line, the file is still there.

### Where to find it

`build/patch-debug.zip`, relative to your project root. Codemagic respects `$CM_EXPORT_DIR`, so it also shows up in your build artifacts there. On other CI providers, archive it before the runner is torn down.

### What is inside

The compiled Dart snapshots from both sides of the link, plus the link metadata Shorebird uses to compute the shared-code percentage. That is enough to reproduce the link and identify which code was not shared, without access to your project.

Note

`patch-debug.zip` contains your app’s compiled Dart code. It is only partially compiled and names may not be obfuscated, so treat it as more sensitive than the binary you ship publicly, though less sensitive than your source. It contains no Shorebird credentials.

### How to send it

Send your app ID, the release version, and the file.

A [GitHub issue](https://github.com/shorebirdtech/shorebird/issues) is usually easiest, and a public upload is fine for most apps. For a private app, use [Discord](https://discord.gg/shorebird), <contact@shorebird.dev>, or your shared Slack channel if you are an enterprise customer.

***

## Resolving persistent compile or build failures

If you encounter persistent compilation issues or strange env errors that standard builds do not trigger, the local compilation state or tool caches might be corrupted. You can clear all cached build states and tools to start fresh:

1. **Verify environment health**:

   ```
   shorebird doctor
   ```

2. **Clean standard build directories**:

   ```
   flutter clean
   ```

3. **Clean the Shorebird tools cache**:

   ```
   shorebird cache clean
   ```

4. Re-run your release or patch command.

***

## Sign-in and credential errors

`shorebird` signs in with the first credential it finds: an API key in `SHOREBIRD_TOKEN`, then GitHub Actions OIDC, then your `shorebird login`. Run `shorebird auth status` to see which one it’s using (Shorebird 1.6.130 and newer). Find the message you see:

* `You must be logged in to run this command.` No credential was found. On your machine, run `shorebird login`. In CI, set `SHOREBIRD_TOKEN` to an API key (see [CI setup](/code-push/ci/generic/)) or, in GitHub Actions, set up [OIDC sign-in](/account/trust-rules/).
* `Your Shorebird login has expired.` or `The Shorebird auth service rejected your stored credentials (...)`. Your stored `shorebird login` can’t be refreshed. Run `shorebird login` again.
* `Could not refresh your Shorebird credentials: Could not reach the Shorebird auth service.` or `Could not refresh your Shorebird credentials: The Shorebird auth service sent an unexpected answer.` Your login is unchanged, but the CLI couldn’t get an answer from `auth.shorebird.dev` it could use, such as when a proxy answers instead. Check your network, then try again. Behind a proxy or firewall, see [below](#shorebird-commands-fail-with-networktls-connection-errors-behind-a-proxy).
* `SHOREBIRD_TOKEN is not a Shorebird API key (API keys start with sb_api_).` The variable holds something other than an API key, most often a token from the old `shorebird login:ci`. Create an API key in the [Shorebird Console](https://console.shorebird.dev) and set it as `SHOREBIRD_TOKEN`.
* `No Shorebird account found for these credentials.` The credentials are valid, but no Shorebird account matches them. Create an account in the [Shorebird Console](https://console.shorebird.dev), or use the account you have: run `shorebird logout` and `shorebird login`, or set `SHOREBIRD_TOKEN` to one of its API keys.

For errors from GitHub Actions OIDC sign-in, see [When a sign-in is refused](/account/trust-rules/#when-a-sign-in-is-refused).

***

## Shorebird commands fail with network/TLS connection errors behind a proxy

If your development machine or CI/CD runner is situated behind a corporate proxy or firewall, Shorebird CLI commands may fail to connect to Shorebird servers, showing timeout or TLS handshake errors.

To resolve this:

1. **Configure proxy environment variables**: Ensure that standard CLI proxy environment variables are set up in your terminal session:

   * **macOS/Linux**:

     ```
     export HTTP_PROXY="http://your-proxy-server:port"
     export HTTPS_PROXY="http://your-proxy-server:port"
     export NO_PROXY="localhost,127.0.0.1"
     ```

   * **Windows (PowerShell)**:

     ```
     $env:HTTP_PROXY="http://your-proxy-server:port"
     $env:HTTPS_PROXY="http://your-proxy-server:port"
     $env:NO_PROXY="localhost,127.0.0.1"
     ```

2. **Allow Shorebird’s hosts**: Ensure your company firewall allows outbound HTTPS traffic (on port `443`) to every host in [Hosts Shorebird uses](/system/firewalls-and-mirrors/#hosts-shorebird-uses). That page also covers Gradle’s separate proxy settings and how to download from an internal mirror instead.

***

## Patch download size is unexpectedly large

Shorebird patches are usually small (a few hundred KB) because they only download the binary diff (patch artifact) of your compiled Dart code compared to the release version. If a patch size is unexpectedly large (several MBs):

1. **Upgraded dependencies**: Adding or upgrading large third-party packages in your `pubspec.yaml` can significantly change your compilation graph, causing a cascading code change that results in a larger diff.
2. **Code generators**: Extensive updates to code generation tools (e.g., `build_runner`, `freezed`, `json_serializable`) may modify large amounts of boilerplate code across dozens of files, resulting in a larger binary diff.
3. **Obfuscation**: you don’t need to match the release’s obfuscation yourself. `shorebird patch` obfuscates the patch automatically when the release was built with `--obfuscate`, so leave the flag off. In CI, always pass `--release-version`; see [Common causes](/code-push/performance/#common-causes). Passing `--obfuscate` for a release built without obfuscation fails with `--obfuscate was passed, but release <version> was not built with obfuscation.` A patch can’t change a release’s obfuscation mode; create a new release instead. On every platform but iOS, a release built with `--obfuscate` on Flutter older than 3.41.2 can’t share its obfuscated names with its patches, so those patches are obfuscated independently and can be larger. A new release on Flutter 3.41.2 or newer avoids this.
