Troubleshooting
Almost every Patch failure is one of five: the fingerprint gate refused the push, a function you expected to ship stayed native, the WebAssembly toolchain is missing, a device is not picking the update up, or a patch misbehaved in production. Each one has a section below with the command that diagnoses it. Product questions — Apple’s rules, pricing, what can be patched — are answered on the FAQ.
push/release says “FINGERPRINT MISMATCH” — what now?
Section titled “push/release says “FINGERPRINT MISMATCH” — what now?”Your native shell changed since the last App Store release (a native .swift file, a bridge toggle, Info.plist, entitlements, a linked framework, the deployment target, or the compiler version), so the OTA module isn’t compatible with installed apps. Run patchcli fingerprint diff to see exactly what changed. Ship the change through the App Store, then re-baseline with patchcli fingerprint register after the new build is live. Pure-logic patches never trip this — only native-shell changes do. The full diagnosis walkthrough is on The compatibility fingerprint.
My app stopped compiling after patchcli init or prepare
Section titled “My app stopped compiling after patchcli init or prepare”Run patchcli prepare --verify. It builds the prepared project and keeps native any view whose generated code breaks the build, restoring that view’s source, then rebuilds until the build is clean. Those views are recorded under native_views: in .Patch.yml, so later runs remember them. An error that is still there once Patch’s changes are removed is reported as your project’s own, not Patch’s. --verify builds Debug and then the configuration your scheme archives with (usually Release), because an optimized build can fail where Debug doesn’t; --verify-config debug builds only Debug and roughly halves the time. If most views fail in Patch-generated code, or the compiler crashes on it, that is a Patch bug: nothing is kept native, the command exits non-zero naming your patchcli and Xcode versions, and patchcli unprepare restores your project. init runs this step by default (Debug only; add --verify-release). Add --report patch-compatibility.md to get the per-view table, and please send it with a bug report. To remove everything prepare generated, run patchcli unprepare (add --remove-sdk to also remove the package and startup code).
My function stayed native — why isn’t it updatable?
Section titled “My function stayed native — why isn’t it updatable?”It touches a must-stay-native API (low-level platform rendering, the file system, threads, the ObjC runtime, unsafe pointers, or device/OS APIs) somewhere it depends on, or it relies on a bridge you disabled in .Patch.yml. Logic and async/await code is updatable, and SwiftUI view code is updatable when SwiftUI coverage is enabled — run patchcli build --verbose (or patchcli analyze ./Sources --verbose) to see the per-function classification and the reason each eligible function wasn’t emitted. Factoring the pure logic out of a UI/IO function usually moves it into the WASM bucket.
“WASM toolchain NOT FOUND” during build
Section titled ““WASM toolchain NOT FOUND” during build”You need the swift.org toolchain plus the WebAssembly Swift SDK — the Apple/Xcode toolchain cannot target wasm32-unknown-wasi. Install with swiftly install 6.3.2 and swift sdk install https://download.swift.org/swift-6.3.2-release/wasm-sdk/swift-6.3.2-RELEASE/swift-6.3.2-RELEASE_wasm.artifactbundle.tar.gz --checksum a61f0584c93283589f8b2f42db05c1f9a182b506c2957271402992655591dd7c. Without them, patchcli build still generates sources and a coverage report (effectively a dry run) but emits no .wasm. patchcli setup installs both for you.
The device isn’t picking up my update
Section titled “The device isn’t picking up my update”Check three things: (1) the app is on the same channel you shipped to; (2) the device is inside the current rollout % — raise it if you’re staging; (3) the app’s fingerprint matches the release. Devices resolve the active release through the update-check API, so changes apply on the next poll. With start() the update applies on the next launch/check; with the imperative API you must call fetchUpdate() then reloadAsync() yourself.
A patch caused errors in production — how do I recover?
Section titled “A patch caused errors in production — how do I recover?”Run patchcli rollback --channel <channel> to re-activate the previous module; it propagates within ~60s, and a device already running the withdrawn release is told to deactivate and fall back. On-device, the SDK already recovers automatically — if a module fails to verify or activate, it falls back to the previous good module (or the bundled native code) so the app keeps working. Watch the failure rate with patchcli status; it warns past 2%.
My build fails only in CI, not on my machine
Section titled “My build fails only in CI, not on my machine”The usual cause is PATH order. Building the CLI for a Mac uses the Apple toolchain; compiling patches uses the swift.org one, and if swiftly is first on the PATH a host build picks the wrong compiler. Put /usr/bin first for host builds and ~/.swiftly/bin first for WebAssembly builds, or let patchcli setup and patchcli doctor handle it. A toolchain difference between the machine that registered the fingerprint and the machine that releases also produces a mismatch — register and release from the same environment.
How do I file a useful bug report?
Section titled “How do I file a useful bug report?”Two commands make a report actionable without anyone needing your source. patchcli doctor --json reports the versions, the toolchain and the project setup, with a fix hint per gap. patchcli fingerprint diff --explain lists which functions are native and why, and what moved since the registered fingerprint. Attach both to an issue on
patch-release/patch-swift.
Related
Section titled “Related”- FAQ — Apple’s rules, coverage, pricing, rollback, self-hosting
- The compatibility fingerprint — the full mismatch walkthrough
- What Patch can & can’t update — why a view stayed native
- Glossary — fingerprint, demote-to-native, host bridge, PMOD
- The iOS hotfix playbook
Ready to ship your first patch?
Section titled “Ready to ship your first patch?”Install the CLI, run patchcli init, and patchcli release a fix this afternoon.