{"record":{"id":"1d364bb0691326b1","repo":"PaddlePaddle/PaddleOCR","slug":"could-not-parse-xcresulttool-json-e","errorCode":null,"errorMessage":"Could not parse xcresulttool JSON: {e}.","messagePattern":"Could not parse xcresulttool JSON: (.+?)\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"deploy/ios_demo/scripts/extract_xcresult_attachments.py","lineNumber":112,"sourceCode":"            \"tests\",\n            \"--path\",\n            str(result_path),\n            \"--format\",\n            \"json\",\n        ]\n    )\n    if r.returncode != 0:\n        raise SystemExit(\n            _die(\n                f\"xcresulttool get test-results failed with exit {r.returncode}.\",\n                str(result_path),\n                \"Confirm the .xcresult was produced by a completed `xcodebuild test`.\",\n            )\n        )\n    try:\n        return json.loads(r.stdout or b\"{}\")\n    except json.JSONDecodeError as e:\n        raise SystemExit(\n            _die(\n                f\"Could not parse xcresulttool JSON: {e}.\",\n                str(result_path),\n                \"Re-run xcodebuild test to regenerate the .xcresult.\",\n            )\n        )\n\n\ndef _collect_test_case_urls(node: dict) -> List[str]:\n    urls: List[str] = []\n    if node.get(\"nodeType\") == \"Test Case\":\n        u = node.get(\"nodeIdentifierURL\")\n        if isinstance(u, str) and u.startswith(\"test://\"):\n            urls.append(u)\n    for ch in node.get(\"children\") or []:\n        urls.extend(_collect_test_case_urls(ch))\n    return urls\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/deploy/ios_demo/scripts/extract_xcresult_attachments.py#L94-L130","documentation":"Raised as SystemExit when `xcrun xcresulttool get test-results` exits 0 but its stdout is not valid JSON. The script parses the tool's stdout with json.loads to enumerate test cases, so any non-JSON text (warnings, prompts, corrupt bundle output) makes parsing fail. The _die helper prints the parse error, the .xcresult path, and tells you to re-run xcodebuild test.","triggerScenarios":"Running extract_xcresult_attachments.py against an .xcresult that is corrupted, truncated, or produced by an incompatible Xcode version; xcresulttool printing a license/prompts/warnings to stdout before the JSON; passing a directory that is not a real .xcresult bundle.","commonSituations":"Xcode upgraded after the bundle was generated (xcresulttool format mismatch), CI copying the .xcresult without its full bundle structure, or xcodebuild test being interrupted so the result bundle is incomplete.","solutions":["Re-run `xcodebuild test` to regenerate a complete .xcresult bundle, then retry the script.","Verify the bundle manually: `xcrun xcresulttool get test-results tests --path <bundle>` and confirm the output is JSON.","Confirm the selected Xcode (`xcode-select -p`) is the same version that produced the bundle; switch or regenerate if not.","Check the bundle is a complete directory (not zipped/transferred partially) and re-copy it if needed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import json, subprocess\n\ndef xcresult_tests_valid(bundle: str) -> bool:\n    r = subprocess.run(\n        [\"xcrun\", \"xcresulttool\", \"get\", \"test-results\", \"tests\", \"--path\", bundle],\n        capture_output=True, text=True,\n    )\n    if r.returncode != 0:\n        return False\n    try:\n        json.loads(r.stdout)\n        return True\n    except json.JSONDecodeError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    run_extract_script(bundle)\nexcept SystemExit as e:\n    # _die printed cause + next step to stderr; surface it, do not retry blindly\n    log.error(\"xcresult extraction failed (exit %s); regenerate the bundle\", e.code)\n    raise","preventionTips":["Always run extract_xcresult_attachments.py against a freshly generated .xcresult from a completed xcodebuild test.","Keep Xcode version consistent between bundle generation and extraction (xcode-select -p).","Copy .xcresult bundles as whole directories, never partial zips."],"tags":["ios","xcodebuild","xcresult","json","cli"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}