{"record":{"id":"c32d9d9f8221aac8","repo":"PaddlePaddle/PaddleOCR","slug":"xcresulttool-metrics-export-failed","errorCode":null,"errorMessage":"xcresulttool metrics export failed","messagePattern":"xcresulttool metrics export failed","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"deploy/ios_demo/scripts/extract_xctest_metrics.py","lineNumber":61,"sourceCode":"\ndef export_metrics(result: Path) -> Dict[str, Any]:\n    proc = subprocess.run(\n        [\n            \"xcrun\",\n            \"xcresulttool\",\n            \"get\",\n            \"test-results\",\n            \"metrics\",\n            \"--path\",\n            str(result),\n            \"--compact\",\n        ],\n        text=True,\n        capture_output=True,\n        check=False,\n    )\n    if proc.returncode != 0:\n        raise RuntimeError(proc.stderr.strip() or \"xcresulttool metrics export failed\")\n    raw = json.loads(proc.stdout or \"[]\")\n    tests = raw if isinstance(raw, list) else []\n    memory_metrics: List[Dict[str, Any]] = []\n    for test in tests:\n        if not isinstance(test, dict):\n            continue\n        for run in test.get(\"testRuns\") or []:\n            if not isinstance(run, dict):\n                continue\n            device = run.get(\"device\") if isinstance(run.get(\"device\"), dict) else {}\n            config = (\n                run.get(\"testPlanConfiguration\")\n                if isinstance(run.get(\"testPlanConfiguration\"), dict)\n                else {}\n            )\n            for metric in run.get(\"metrics\") or []:\n                if not isinstance(metric, dict):\n                    continue","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/deploy/ios_demo/scripts/extract_xctest_metrics.py#L43-L79","documentation":"RuntimeError raised when `xcrun xcresulttool get test-results metrics --path <bundle> --compact` exits non-zero in extract_xctest_metrics.py. The message is the tool's stripped stderr, or the generic 'xcresulttool metrics export failed' when stderr is empty.","triggerScenarios":"Running the metrics extraction against an .xcresult that contains no metrics payloads (tests ran without performance measurement); a corrupt or non-metrics bundle; an Xcode whose xcresulttool lacks the metrics subcommand.","commonSituations":"CI running the script on every test result although only XCTest performance tests (measure {}) produce metrics; Xcode downgrade/upgrade changing the metrics export format.","solutions":["Read the stderr text embedded in the RuntimeError to identify the xcresulttool complaint.","Ensure the .xcresult comes from tests that use XCTest metrics (measure blocks) — plain unit tests produce no metrics.","Regenerate the bundle with `xcodebuild test` on the currently selected Xcode.","Check `xcrun xcresulttool help get test-results` lists `metrics` for your Xcode version."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import subprocess\n\ndef metrics_available(bundle: str) -> bool:\n    r = subprocess.run(\n        [\"xcrun\", \"xcresulttool\", \"get\", \"test-results\", \"metrics\", \"--path\", bundle, \"--compact\"],\n        capture_output=True, text=True,\n    )\n    return r.returncode == 0","typeGuard":null,"tryCatchPattern":"try:\n        extract_metrics(result_path)\nexcept RuntimeError as e:\n    if \"xcresulttool\" in str(e):\n        log.warning(\"no metrics in %s; skipping (only performance tests produce metrics)\", result_path)\n    else:\n        raise","preventionTips":["Only run extract_xctest_metrics.py on bundles from XCTest performance tests (measure blocks).","Gate the metrics step in CI on the test suite containing metrics tests.","Verify the metrics subcommand exists for the selected Xcode before invoking."],"tags":["ios","xcresult","metrics","cli"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}