Skip to main content

Troubleshooting and Error Codes

When a tk-ota-push (alias tkushpatch) command fails, the CLI returns a standard POSIX exit code (sysexits.h) and outputs a diagnostic error message to standard error (stderr).

This troubleshooting guide explains all CLI exit codes and provides step-by-step solutions to resolve build failures, authentication issues, and server rejections.


1. CLI Exit Code Reference​

Exit CodePOSIX ConstantExact Cause in runner.dartQuick Fix
0EX_OKCommand executed successfullyNo action required.
1EX_SOFTWAREGeneral execution error, Flutter build failure, native code tampering detected, or HTTP 4xx/5xx API rejectionInspect the detailed error message and follow diagnostic steps below.
64EX_USAGEInvalid command syntax, unrecognized option, or out-of-range argument value (e.g., --rollout 150)Review usage syntax using tk-ota-push <command> --help.
66EX_NOINPUTNo valid pubspec.yaml file found in the targeted directoryVerify your current working directory or pass --project <path>.
69EX_UNAVAILABLEShorebird toolchain not found (~/.shorebird/bin/cache/flutter)Install or initialize Shorebird on the system.

2. Detailed Diagnostic & Step-by-Step Resolution​

Error 1: Shorebird Toolchain Not Found (Exit Code 69)​

Toolchain Shorebird introuvable (~/.shorebird/bin/cache/flutter).

Diagnostic​

The Toolchain.locate() method inspects $HOME/.shorebird/bin/cache/flutter (or %USERPROFILE%\.shorebird\bin\cache\flutter on Windows). If this folder does not exist or lacks patched Flutter artifacts, execution aborts immediately.

Resolution​

  1. Install Shorebird if not already present on the machine:
    curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
  2. Initialize the patched Flutter engine cache by running doctor:
    shorebird doctor
  3. Verify that the cache folder exists and contains Flutter binaries:
    ls -la ~/.shorebird/bin/cache/flutter

Error 2: No pubspec.yaml in . (Exit Code 66)​

Aucun pubspec.yaml dans /Users/dev/workspace.

Diagnostic​

The command was executed outside of a valid Flutter project root, or the path specified with --project points to a non-existent directory.

Resolution​

  • Navigate to your Flutter project directory before running commands:
    cd path/to/my_flutter_app
    tk-ota-push patch ...
  • Alternatively, provide an explicit project path:
    tk-ota-push patch --project /path/to/my_flutter_app ...

Error 3: HTTP 409 Conflict — Release Already Locked (Exit Code 1)​

❌ ERREUR HTTP 409 CONFLICT — PROTECTION CONTRE LE 'RELEASE OVERWRITE'
La Release '1.0.0+1' (android / aarch64) est DÉJÀ verrouillée dans database !
Empreinte SHA-256 de référence : 4f8b2c...

Diagnostic​

TkushPatch enforces strict immutability for baseline Releases. Once a Release (e.g., 1.0.0+1) is locked on the server, its baseline binary can never be overwritten because deployed client devices rely on its exact byte footprint to compute differential binary diffs (binary diff).

Resolution​

  • If you intend to deliver an OTA bug fix without resubmitting to App Stores: use the patch subcommand instead of release:
    tk-ota-push patch 1.0.0+1 -p android -m "Patch description"
  • If you are preparing a new App Store / Play Store binary: bump the version number in pubspec.yaml (e.g., 1.0.0+2 or 1.0.1+1) before invoking release:
    tk-ota-push release 1.0.0+2 -p android --artifact aab

Error 4: Native Code Alteration Detected (Exit Code 1)​

❌ ERREUR CRITIQUE D'INTÉGRITÉ NATIVE :
Des modifications de code natif ont été détectées entre la Release
de référence et le patch que vous tentez de publier :
- classes.dex : MODIFIÉ (Code Kotlin/Java altéré)

Diagnostic​

The NativeIntegrityScanner detected changes in Android bytecode files (classes*.dex), the app manifest (AndroidManifest.xml), native C++ libraries, or iOS native frameworks. An OTA patch can only safely hot-swap Dart AOT code; pushing this patch would trigger fatal crashes on devices.

Resolution​

  • This update requires a full Store release. Bump the version in pubspec.yaml and publish a new Release:
    tk-ota-push release 1.0.1+2 -p android --artifact aab
  • If you are certain that the changes affect only pure Dart packages (and only pubspec.lock drifted), use the --force flag:
    tk-ota-push patch 1.0.0+1 -p android --force -m "Pure Dart intl upgrade"

Error 5: PKCE Login Timeout (Exit Code 1)​

Échec de la connexion : Délai dépassé (aucun retour de l'interface Web)

Diagnostic​

tk-ota-push login spun up a local loopback HTTP server on 127.0.0.1, but no authorization callback arrived within the 3-minute timeout window (browser blocked, local firewall restricting loopback requests, or Web portal unreachable).

Resolution​

  1. Verify the Web Console is reachable at the configured address (or specify --web-url https://console-ota.enterprise.com).
  2. Manually click the authorization link displayed in the terminal if your default browser did not open automatically.
  3. In headless CI/CD runners or remote SSH sessions, avoid login: set the OTA_API_KEY environment variable instead.

Error 6: --rollout Must Be Between 0 and 100 (Exit Code 64)​

Erreur : --rollout doit être un entier compris entre 0 et 100 (reçu: 150).

Diagnostic​

The value provided to the --rollout option on patch is not a valid integer between 0 and 100.

Resolution​

Provide an integer percentage between 0 and 100:

tk-ota-push patch 1.0.0+1 -p android --rollout 25 -m "Canary 25%"

Error 7: HTTP 403 Forbidden During Patch Promotion (Exit Code 1)​

Erreur lors de la promotion (403) : {"error":"FORBIDDEN","message":"Patch must be in STAGED status and approved by a different user"}

Diagnostic​

Promoting a patch to the stable channel enforces the 4-Eyes Governance Rule. The server rejects promotion if:

  • The user attempting promotion authored the original patch (author_id == approver_id).
  • The patch was not originally published with the --staged flag or has not received the required approval.

Resolution​

  1. Log in with a separate account possessing approval permissions (ROLE_SECURITY_OFFICER or ROLE_TENANT_ADMIN).
  2. Approve the patch via the Web Console (Governance tab) or execute promote using the approver's API key.