{"record":{"id":"64e340a84c1c0cbd","repo":"dotnet/runtime","slug":"comparison-failed-for-the-following-files-s","errorCode":null,"errorMessage":"Comparison failed for the following files(s): {}","messagePattern":"Comparison failed for the following files\\(s\\): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/coreclr/scripts/utilities.py","lineNumber":96,"sourceCode":"    \"\"\"Updates dest directory with files from src directory\n\n    Args:\n        destpath (str): The destination path to sync with the source\n        srcpath (str): The source path to sync to the destination\n        recursive(boolean): If True, descend into and update subdirectories (default: True)\n        destructive(boolean): If True, delete files in the destination which do not exist in the source (default: True)\n        shallow(boolean): If True, only use os.stat to diff files. Do not examine contents (default: False)\n    \"\"\"\n    srcfiles, srcdirs = split_entries(os.listdir(srcpath), srcpath)\n    dstfiles, dstdirs = split_entries(os.listdir(dstpath), dstpath)\n\n\n    # Update files in both src and destination which are different in destination\n    commonfiles = srcfiles.intersection(dstfiles)\n    _, mismatches, errors = filecmp.cmpfiles(srcpath, dstpath, commonfiles, shallow=shallow)\n\n    if errors:\n        raise RuntimeError(\"Comparison failed for the following files(s): {}\".format(errors))\n\n    for mismatch in mismatches:\n        shutil.copyfile(os.path.join(srcpath, mismatch), os.path.join(dstpath, mismatch))\n\n    # Copy over files from source which do not exist in the destination\n    for missingfile in srcfiles.difference(dstfiles):\n        shutil.copyfile(os.path.join(srcpath, missingfile), os.path.join(dstpath, missingfile))\n\n    #If destructive, delete files in destination which do not exist in sourc\n    if destructive:\n        for deadfile in dstfiles.difference(srcfiles):\n            print(deadfile)\n            os.remove(os.path.join(dstpath, deadfile))\n\n        for deaddir in dstdirs.difference(srcdirs):\n            print(deaddir)\n            shutil.rmtree(os.path.join(dstpath, deaddir))\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/coreclr/scripts/utilities.py#L78-L114","documentation":"Raised by update_directory() in utilities.py at src/coreclr/scripts/utilities.py:96 when filecmp.cmpfiles reports a non-empty errors list — files present in both source and destination that could not be compared due to an OS-level error (permission denied, file vanished mid-comparison, etc.).","triggerScenarios":"A file exists in both srcpath and dstpath but cmpfiles fails to read/stat it; locked files on Windows; files deleted by another process during the sync.","commonSituations":"Antivirus locking files on Windows Helix; a concurrent process writing to dstpath; permission mismatch between source and destination.","solutions":["Ensure the process has read access to all common files in srcpath and dstpath.","Stop concurrent processes that may lock or delete files during the sync.","Retry — a file may have been transiently locked.","On Windows, exclude the directories from antivirus on-access scanning."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import os, stat\nfor d in (srcpath, dstpath):\n    for entry in os.listdir(d):\n        p = os.path.join(d, entry)\n        if os.path.isfile(p) and not os.access(p, os.R_OK):\n            raise SystemExit(f'Unreadable file before sync: {p}')","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        update_directory(srcpath, dstpath, recursive=True, destructive=True, shallow=False)\n        break\n    except RuntimeError as e:\n        if 'Comparison failed' in str(e) and attempt < 2:\n            time.sleep(2)\n            continue\n        raise","preventionTips":["Avoid running other processes that touch dstpath during update_directory().","Run syncs with sufficient file permissions and disable AV on-access scanning on the work tree."],"tags":["dotnet","coreclr","superpmi","filesystem","windows"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}