{"record":{"id":"ef57d89dfb8da360","repo":"stablyai/orca","slug":"emulator-error-ef57d8","errorCode":"emulator_error","errorMessage":"Cannot parse empty uiautomator XML","messagePattern":"Cannot parse empty uiautomator XML","errorType":"exception","errorClass":"EmulatorError","httpStatus":null,"severity":"error","filePath":"src/main/emulator/android/uiautomator-tree.ts","lineNumber":41,"sourceCode":"export function parseAndroidBounds(value: string): AndroidAxBounds | null {\n  const match = value.trim().match(/^\\[(-?\\d+),(-?\\d+)\\]\\[(-?\\d+),(-?\\d+)\\]$/)\n  if (!match) {\n    return null\n  }\n  return {\n    left: Number(match[1]),\n    top: Number(match[2]),\n    right: Number(match[3]),\n    bottom: Number(match[4])\n  }\n}\n\n// Parses uiautomator dump XML. The returned node is the synthetic root that\n// holds the top-level <node> children of <hierarchy>. Throws\n// EmulatorError('emulator_error', ...) on unparseable input.\nexport function parseUiAutomatorXml(xml: string): AndroidAxNode {\n  if (xml.trim() === '') {\n    throw new EmulatorError('emulator_error', 'Cannot parse empty uiautomator XML')\n  }\n  let root: RawElement\n  try {\n    root = parseDocument(xml)\n  } catch (error) {\n    if (error instanceof EmulatorError) {\n      throw error\n    }\n    throw new EmulatorError(\n      'emulator_error',\n      `Failed to parse uiautomator XML: ${(error as Error).message}`\n    )\n  }\n  // A bare <node> root is treated as the single top-level node; otherwise take\n  // the <node> children of <hierarchy>.\n  const topLevel =\n    root.tag === 'node' ? [root] : root.children.filter((child) => child.tag === 'node')\n  return { children: topLevel.map(mapNode) }","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/emulator/android/uiautomator-tree.ts#L23-L59","documentation":"Thrown by parseUiAutomatorXml when the input string is empty or whitespace-only. It is the first guard before attempting to parse the XML document, distinguishing 'no data' from 'malformed data'. An empty dump usually means `adb shell uiautomator dump` produced no output — the command ran but wrote nothing.","triggerScenarios":"parseUiAutomatorXml('') or parseUiAutomatorXml('   \\n') called with the result of a uiautomator dump that returned an empty string. This precedes the parseDocument call, so it short-circuits before any XML parsing.","commonSituations":"The uiautomator dump command failed silently (exit 0, empty stdout) on a device where the window manager is not ready; the dump file read failed; the device booted but the UI is not yet rendered; a headless window with no views; an outdated uiautomator binary returning nothing.","solutions":["Wait for the device UI to be ready (e.g. sys.boot_completed AND a launcher activity) before dumping.","Re-run the uiautomator dump and inspect raw stdout length before parsing; retry with backoff if empty.","Run `adb shell uiautomator dump /sdcard/x.xml && adb shell cat /sdcard/x.xml` manually to see what the device emits.","If the dump is legitimately empty (no views), handle the empty case upstream rather than feeding it to the parser."],"exampleFix":"// before: parsing whatever dump returns\nconst tree = parseUiAutomatorXml(dump.stdout)\n// after: retry on empty until UI is ready\nif (dump.stdout.trim() === '') { await sleep(500); reDump() }\nconst tree = parseUiAutomatorXml(dump.stdout)","handlingStrategy":"validation","validationCode":"// Skip parsing when the dump is empty; re-dump instead.\nfunction hasDump(xml: string): boolean { return xml.trim() !== '' }","typeGuard":null,"tryCatchPattern":"if (!hasDump(xml)) { await sleep(500); xml = await redump() }\nif (hasDump(xml)) return parseUiAutomatorXml(xml)\nthrow new Error('uiautomator dump empty after retry')","preventionTips":["Wait for sys.boot_completed and a launcher activity before dumping the UI tree.","Retry the dump with backoff when it returns empty.","Inspect raw `adb shell uiautomator dump` output when empty dumps persist."],"tags":["android","uiautomator","accessibility","validation","emulator"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}