expo/expo · error · CommandError

Unable to launch app, number of tries exceeded

Error message

Unable to launch app, number of tries exceeded

What it means

The companion error to 153: the launch retry loop tolerates 'EBusy'/'ENotFound' for up to 3 attempts with a 500ms backoff (delayAsync). If all three attempts still return a busy/not-found status, the loop exits and throws this CommandError. It means the device/debugserver was persistently unavailable during the launch window.

Source

Thrown at packages/@expo/cli/src/run/ios/appleDevice/AppleDevice.ts:296

        debugEvent('apple_device:disconnect_response', { result: res });
        if (res !== 'OK') {
          console.warn(
            'Something went wrong while attempting to disconnect from iOS debug server, you may need to reopen the app manually.'
          );
        }
      }

      return debugServerClient;
    } else if (result === 'EBusy' || result === 'ENotFound') {
      debugEvent('apple_device:launch_retry', { tries });
      tries++;
      debugServerClient.socket.end();
      await delayAsync(500);
    } else {
      throw new CommandError(`There was an error launching app: ${result}`);
    }
  }
  throw new CommandError('Unable to launch app, number of tries exceeded');
}

/**
 * iOS 17 introduces a new protocol called RemoteXPC.
 * This is not yet implemented, so we fallback to devicectl.
 *
 * @see https://github.com/doronz88/pymobiledevice3/blob/master/misc/RemoteXPC.md#process-remoted
 */
async function launchApp(
  clientManager: ClientManager,
  {
    bundleId,
    appInfo,
    detach,
  }: { bundleId: string; appInfo: IPLookupResult[string]; detach?: boolean }
) {
  try {
    return await launchAppWithUsbmux(clientManager, { appInfo, detach });

View on GitHub (pinned to b09195aac2)

Solutions

  1. Wait a few seconds and re-run; the device usually frees up.
  2. Close other tools that talk to the device over USB (Xcode, Finder sync, iMazing).
  3. Unplug/replug the device or restart it to reset the debugserver state.
  4. If it persists on iOS 17+, the RemoteXPC/devicectl fallback path may be needed — update @expo/cli to a version with iOS 17 support.
Defensive patterns

Strategy: retry

Try / catch

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    return await launchOnDevice(...);
  } catch (e) {
    if (e instanceof CommandError && /number of tries exceeded/.test(e.message) && attempt < 2) {
      await delay(2000); // longer than the inner 500ms backoff
      continue;
    }
    throw e;
  }
}

Prevention

When it happens

Trigger: Three consecutive checkLaunchSuccess() calls returning 'EBusy' or 'ENotFound' within ~1.5s: a device that is still processing a previous install/launch, SpringBoard busy, a long app-attach/signing operation in progress, or a debugserver that is overloaded.

Common situations: Rapidly re-running run:ios without letting the previous install finish; a low-powered device (older iPhones) where 500ms×3 is not enough; USB throughput contention with other tools (Xcode, iMazing) holding the device; iOS beta instability.

Related errors


AI-assisted analysis of expo/expo@b09195aac2 (2026-08-12). Data as JSON: /api/errors/e4fd292a18649c95. Report an issue: GitHub.