{"record":{"id":"1b0f7cb14d23df18","repo":"stablyai/orca","slug":"etimedout","errorCode":"ETIMEDOUT","errorMessage":"security timed out after ${KEYCHAIN_COMMAND_TIMEOUT_MS}ms","messagePattern":"security timed out after (.+?)ms","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/claude-accounts/keychain.ts","lineNumber":192,"sourceCode":"          (error as { message?: unknown }).message ?? ''\n        )}`.toLowerCase()\n      : String(error).toLowerCase()\n  return code === 44 || message.includes('could not be found') || message.includes('not be found')\n}\n\nfunction execSecurityCommand(args: string[]): Promise<SecurityCommandResult> {\n  return new Promise((resolve, reject) => {\n    let settled = false\n    let child: ReturnType<typeof execFile> | undefined\n    const timer = setTimeout(() => {\n      if (settled) {\n        return\n      }\n      settled = true\n      child?.kill()\n      reject(\n        Object.assign(new Error(`security timed out after ${KEYCHAIN_COMMAND_TIMEOUT_MS}ms`), {\n          code: 'ETIMEDOUT',\n          stderr: ''\n        })\n      )\n    }, KEYCHAIN_COMMAND_TIMEOUT_MS)\n\n    const settle = (callback: () => void): void => {\n      if (settled) {\n        return\n      }\n      settled = true\n      clearTimeout(timer)\n      callback()\n    }\n\n    // Why: Node's execFile timeout only signals the `security` process; a\n    // stuck callback would otherwise leave auth/keychain operations pending.\n    try {\n      child = execFile(","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/claude-accounts/keychain.ts#L174-L210","documentation":"Rejected by execSecurityCommand() when the macOS `security` child process does not settle within KEYCHAIN_COMMAND_TIMEOUT_MS (3000 ms). The timer kills the child and rejects with code 'ETIMEDOUT'. It guards against a stuck `security` binary (e.g. waiting on a Keychain unlock prompt) that would otherwise leave auth/keychain operations hanging indefinitely.","triggerScenarios":"The Keychain is locked and macOS shows a GUI unlock dialog that `security` (non-interactive) waits on. A system prompt for permission is blocking the process. The security binary is hung due to a corrupted Keychain. Slow/inaccessible iCloud Keychain sync.","commonSituations":"Fresh login after restart where the login Keychain is still locked. MDM policies that require approval for security CLI access. Corrupted login.keychain-db. iCloud Keychain desync causing long stalls.","solutions":["Unlock the login Keychain first (Keychain Access, or `security unlock-keychain`) and retry.","Repair the Keychain with Keychain First Aid / Keychain Access > Keychain Repair.","Increase KEYCHAIN_COMMAND_TIMEOUT_MS only if the environment legitimately needs longer (rare).","Ensure no GUI dialog is pending approval for Orca/security to access the item."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"function isKeychainTimeout(error: unknown): boolean {\n  return (\n    error instanceof Error &&\n    (error as NodeJS.ErrnoException).code === 'ETIMEDOUT' &&\n    error.message.includes('security timed out')\n  )\n}","tryCatchPattern":"try {\n  return await execSecurityCommand(args)\n} catch (error) {\n  if (isKeychainTimeout(error)) {\n    // Likely locked Keychain — surface a user action, then retry once\n    throw new Error('Keychain appears locked. Unlock the login Keychain and retry.')\n  }\n  throw error\n}","preventionTips":["Unlock the login Keychain before issuing security commands.","Grant Orca automation permission for the security CLI.","Repair corrupt Keychains proactively.","Avoid operations while iCloud Keychain is mid-sync."],"tags":["macos","keychain","timeout","security","etimedout"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}