expo/expo · warning · CommandError

APPLE_DEVICE_LOCKED

APPLE_DEVICE_LOCKED

Error message

Device is currently locked.

What it means

Thrown by LockdownProtocolReader.parseBody (code APPLE_DEVICE_LOCKED) when a lockdown plist response contains Error === 'DeviceLocked'. This is the lockdown-layer signal that the device screen is locked, and it is the primary source of the APPLE_DEVICE_LOCKED code that bubbles up to installOnDeviceAsync's interactive unlock-retry prompt. It is raised before any service-specific logic runs, because most lockdown operations require an unlocked device.

Source

Thrown at packages/@expo/cli/src/run/ios/appleDevice/protocol/LockdownProtocol.ts:72

  constructor(socket: Socket) {
    super(socket, new ProtocolReaderFactory(LockdownProtocolReader), new LockdownProtocolWriter());
  }
}

export class LockdownProtocolReader extends PlistProtocolReader {
  constructor(callback: (data: any) => any) {
    super(LOCKDOWN_HEADER_SIZE, callback);
  }

  parseHeader(data: Buffer) {
    return data.readUInt32BE(0);
  }

  parseBody(data: Buffer) {
    const resp = super.parseBody(data);
    if (isLockdownErrorResponse(resp)) {
      if (resp.Error === 'DeviceLocked') {
        throw new CommandError('APPLE_DEVICE_LOCKED', 'Device is currently locked.');
      }

      if (resp.Error === 'InvalidService') {
        let errorMessage = `${resp.Error}: ${resp.Service} (request: ${resp.Request})`;
        if (resp.Service === 'com.apple.debugserver') {
          errorMessage +=
            '\nTry reconnecting your device. You can also debug service logs with `export DEBUG=expo:xdl:ios:*`';
        }
        throw new CommandError('APPLE_DEVICE_LOCKDOWN', errorMessage);
      }

      throw new CommandError('APPLE_DEVICE_LOCKDOWN', resp.Error);
    }
    return resp;
  }
}

export class LockdownProtocolWriter implements ProtocolWriter {

View on GitHub (pinned to b09195aac2)

Solutions

  1. Unlock the device (enter passcode) and retry — installOnDeviceAsync already prompts for this.
  2. Disable auto-lock (Settings → Display & Brightness → Auto-Lock → Never) during development.
  3. Ensure the device is awake by tapping the screen before the operation starts.
  4. For CI, keep the device unlocked via power/screen policy.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.doHandshake(pairRecord);
} catch (err) {
  if (err instanceof CommandError && err.code === 'APPLE_DEVICE_LOCKED') {
    // surface an 'unlock the device' prompt, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: Any lockdown request (GetValue, StartService, StartSession, etc.) issued while the device is locked — lockdown returns a plist with Error='DeviceLocked' and the reader escalates it.

Common situations: Device locked at the moment run:ios / install runs; passcode-required-after-reboot state; device auto-locked during a long build before the install step.

Related errors


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