Read device logs
When a patch doesn’t reach a device, or reaches it and doesn’t run, the device’s logs usually say why. The Shorebird updater writes a line for every patch check, download and install. This page shows how to read those logs on a release build, with no debugger attached, and what the lines mean.
Get the logs
Section titled “Get the logs”Start reading the logs first, then start the app. The updater checks for patches once each time the app’s process starts, so fully close the app before each attempt.
Connect the device over USB (or start the emulator) and run:
The first command clears old output. The second shows only the flutter tag,
which is where the updater and Shorebird’s Flutter engine write. To close the
app completely before a new attempt, run
adb shell am force-stop <your.package.name>.
- Connect the device to a Mac and open the Console app.
- Select the device in the sidebar and click Start.
- Type
shorebirdin the search field and press Return. - Start the app on the device.
The updater’s lines contain [shorebird], and the engine’s lines contain
Shorebird, so this search finds both. To keep other apps’ lines out, also
filter on your app’s process, which for a Flutter app is Runner unless you
renamed it.
Open the Console app on the Mac running your app, click Start, type
shorebird in the search field, and press Return. Then start the app. Console
shows the updater’s lines, the ones containing [shorebird].
The engine’s lines, such as Shorebird updater: no active patch., don’t reach
Console on macOS. To see them, start the app from Terminal by running the
executable inside its bundle, for example
/Applications/MyApp.app/Contents/MacOS/MyApp. Those lines print in Terminal.
Start the app from a terminal. The updater writes its lines to that terminal.
If no lines mention Shorebird at all, the app wasn’t built with
shorebird release and can’t receive patches; see
Patch not showing up.
What a working update looks like
Section titled “What a working update looks like”On the launch after you publish a patch, the log has lines like these, with
other lines in between. This is Android, with long values shortened to ...:
On the next launch, the app runs the patch, and the first line names the patch it loads instead:
How to read the patch check request line, including the formats older engines print, is in Patch not showing up.
What the lines mean
Section titled “What the lines mean”The lines below are from releases built with Flutter 3.47.9. Where an older Flutter version prints something different, the section says so.
The update check finished
Section titled “The update check finished”This is the last line of every automatic check.
| Status | Meaning |
|---|---|
No update | The track has no patch for this release that the device doesn’t already have. |
Update installed | A patch downloaded and installed. It runs on the next launch. |
Update had error | The check, download or install failed. An earlier line starting with Update failed:, and any Caused by: lines after it, say why; see the sections below. |
Update available but previously failed to install. Not installing. | The newest patch is one this device has marked bad. See The device skips a patch that failed before. |
Update already in progress | An update() call from your code was already running when this check started. That update carries on. |
The patch check says what’s available
Section titled “The patch check says what’s available”patch_available and patch say whether the track has a patch for this
release, and which one. rolled_back_patch_numbers lists the release’s
rolled back patches; the device removes any of them it
has. If you expected a patch and patch_available is false, check that the
patch is on the track the device asked for (channel in the request line) and
that it wasn’t rolled back.
A patch downloaded
Section titled “A patch downloaded”The patch is installed on the device and runs from the next launch. Nothing else needs to happen. To run it sooner, see Restarting after an update.
The device skips a patch that failed before
Section titled “The device skips a patch that failed before”On releases built with Flutter before 3.41.9, the line is
Patch 2 has previously failed to boot, skipping.
This device has marked patch 2 bad, so it won’t install it again. A patch is marked bad when it fails to load, including when the app’s process ends while the engine is still loading it, and, on Flutter 3.41.9 and newer, when its download fails the checks described in The downloaded patch doesn’t match the release. The device keeps running its previous patch, or the release.
What to do: roll back patch 2 so devices that haven’t tried it yet don’t download it, fix the problem, and publish a new patch. Devices install the new patch number as usual. If the patch crashed an iOS app, see App crashes after a patch installs.
A patch failed to load
Section titled “A patch failed to load”The engine couldn’t load the patch this launch was meant to run, and the device marks the patch bad so it won’t try it again. What the app runs on that launch and later ones depends on the platform and the Flutter version; see Patch integrity and automatic rollback.
The downloaded patch doesn’t match the release
Section titled “The downloaded patch doesn’t match the release”A few lines further on, under Caused by:, is Update rejected: hash mismatch.
The patch downloaded, but applying it to the app on this device didn’t produce
the code Shorebird built, because the app on the device isn’t the build
shorebird release uploaded. See
Patches can’t install because the app isn’t the build Shorebird released.
The device couldn’t reach Shorebird
Section titled “The device couldn’t reach Shorebird”On releases built with Flutter before 3.47.7, the line is
Update failed: Patch check request failed due to network error. Please check your internet connection.
The device is offline, or its network blocks Shorebird. The updater tries again on the next launch, and the device keeps the patch it has.
On releases built with Flutter 3.47.9 and newer, a Caused by: line after it
gives the cause. On Android, iOS and macOS, TLS handshake failed there means
the connection was made but the certificate it got wasn’t trusted; on Windows
and Linux, the same problem shows as a certificate error. That usually means a
proxy or security product on the network inspects HTTPS traffic. These releases
trust the same certificates as the rest of the device: on Android, the ones your
app’s network security configuration allows; on iOS and macOS, the ones the
system trusts, including roots installed by device management; and on Windows
and Linux, the operating system’s trusted certificates. Ask the network’s
administrators to let Shorebird’s traffic through, or have the device trust the
proxy’s root certificate.
The patch check was refused
Section titled “The patch check was refused”Shorebird refused the patch check. The usual cause is that your organization reached its patch install limit; see Your organization reached its patch install limit.
The app is running the release’s own code
Section titled “The app is running the release’s own code”The device has no installed patch, so it runs the release. That’s expected until
a patch has downloaded. If a patch should have arrived by now, compare the
release_version in the patch check request with the release you patched; see
Patch not showing up.
The automatic check is turned off
Section titled “The automatic check is turned off”shorebird.yaml has
auto_update: false, so the app
checks only when your code calls package:shorebird_code_push. See
How devices get patches.