{"record":{"id":"a791ea43a95714b5","repo":"commaai/openpilot","slug":"uncompressed-size-mismatch","errorCode":null,"errorMessage":"Uncompressed size mismatch","messagePattern":"Uncompressed size mismatch","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"openpilot/common/hardware/comma/agnos.py","lineNumber":182,"sourceCode":"    last_p = 0\n    raw_hash = hashlib.sha256()\n    f = unsparsify if partition['sparse'] else noop\n    for chunk in f(downloader):\n      raw_hash.update(chunk)\n      out.write(chunk)\n      p = int(out.tell() / partition['size'] * 100)\n      if p != last_p:\n        last_p = p\n        print(f\"Installing {partition['name']}: {p}\", flush=True)\n\n    if raw_hash.hexdigest().lower() != partition['hash_raw'].lower():\n      raise Exception(f\"Raw hash mismatch '{raw_hash.hexdigest().lower()}'\")\n\n    if downloader.sha256.hexdigest().lower() != partition['hash'].lower():\n      raise Exception(\"Uncompressed hash mismatch\")\n\n    if out.tell() != partition['size']:\n      raise Exception(\"Uncompressed size mismatch\")\n\n    os.sync()\n\n\ndef flash_partition(target_slot_number: int, partition: dict, cloudlog, standalone=False):\n  cloudlog.info(f\"Downloading and writing {partition['name']}\")\n\n  if verify_partition(target_slot_number, partition):\n    cloudlog.info(f\"Already flashed {partition['name']}\")\n    return\n\n  # Clear hash before flashing in case we get interrupted\n  full_check = partition['full_check']\n  if not full_check:\n    clear_partition_hash(target_slot_number, partition)\n\n  path = get_partition_path(target_slot_number, partition)\n","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/common/hardware/comma/agnos.py#L164-L200","documentation":"After writing, out.tell() must equal partition['size']. A size mismatch means the unsparsified output was shorter or longer than the manifest declares — typically truncation from a dropped connection that wasn't caught by the hash checks failing first, or a sparse image whose total block count disagrees with the manifest.","triggerScenarios":"flash_partition where the total bytes written differ from partition['size'] — truncated download stream that ended cleanly, or manifest/image version skew.","commonSituations":"Server closed the connection early with a valid-looking end of stream; mismatched manifest entries; disk/partition target smaller than expected causing short writes.","solutions":["Retry the full flash from scratch","Confirm the manifest and partition images are the same release","Check target device disk health / available space on the partition"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if os.path.getsize(image_path) != partition['size']:\n    redownload(partition)","typeGuard":null,"tryCatchPattern":"try:\n    flash_partition(slot, partition, cloudlog)\nexcept Exception as e:\n    if \"size mismatch\" in str(e):\n        full_redownload_and_retry()","preventionTips":["Check target partition/disk health before flashing","Treat any size mismatch as a corrupted download and start over"],"tags":["firmware","agnos","size-mismatch","flashing"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}