{"record":{"id":"0a89cad0d7c936b5","repo":"expo/expo","slug":"apple-device-locked-0a89ca","errorCode":"APPLE_DEVICE_LOCKED","errorMessage":"Device is currently locked.","messagePattern":"Device is currently locked\\.","errorType":"exception","errorClass":"CommandError","httpStatus":null,"severity":"warning","filePath":"packages/@expo/cli/src/run/ios/appleDevice/protocol/LockdownProtocol.ts","lineNumber":72,"sourceCode":"  constructor(socket: Socket) {\n    super(socket, new ProtocolReaderFactory(LockdownProtocolReader), new LockdownProtocolWriter());\n  }\n}\n\nexport class LockdownProtocolReader extends PlistProtocolReader {\n  constructor(callback: (data: any) => any) {\n    super(LOCKDOWN_HEADER_SIZE, callback);\n  }\n\n  parseHeader(data: Buffer) {\n    return data.readUInt32BE(0);\n  }\n\n  parseBody(data: Buffer) {\n    const resp = super.parseBody(data);\n    if (isLockdownErrorResponse(resp)) {\n      if (resp.Error === 'DeviceLocked') {\n        throw new CommandError('APPLE_DEVICE_LOCKED', 'Device is currently locked.');\n      }\n\n      if (resp.Error === 'InvalidService') {\n        let errorMessage = `${resp.Error}: ${resp.Service} (request: ${resp.Request})`;\n        if (resp.Service === 'com.apple.debugserver') {\n          errorMessage +=\n            '\\nTry reconnecting your device. You can also debug service logs with `export DEBUG=expo:xdl:ios:*`';\n        }\n        throw new CommandError('APPLE_DEVICE_LOCKDOWN', errorMessage);\n      }\n\n      throw new CommandError('APPLE_DEVICE_LOCKDOWN', resp.Error);\n    }\n    return resp;\n  }\n}\n\nexport class LockdownProtocolWriter implements ProtocolWriter {","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/expo/expo/blob/b09195aac27c9e4a63daaf12dcb6f00b6b2e08ee/packages/@expo/cli/src/run/ios/appleDevice/protocol/LockdownProtocol.ts#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Unlock the device (enter passcode) and retry — installOnDeviceAsync already prompts for this.","Disable auto-lock (Settings → Display & Brightness → Auto-Lock → Never) during development.","Ensure the device is awake by tapping the screen before the operation starts.","For CI, keep the device unlocked via power/screen policy."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await client.doHandshake(pairRecord);\n} catch (err) {\n  if (err instanceof CommandError && err.code === 'APPLE_DEVICE_LOCKED') {\n    // surface an 'unlock the device' prompt, then retry\n  }\n  throw err;\n}","preventionTips":["Unlock the device before any lockdown operation.","Disable auto-lock during development.","Re-enter the passcode after a reboot before running device commands."],"tags":["ios","lockdown","device-locked","protocol"],"backgroundTag":null,"analyzedSha":"b09195aac27c9e4a63daaf12dcb6f00b6b2e08ee","analyzedAt":"2026-08-12T15:59:58.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}