dotnet/runtime · error · RuntimeError
Comparison failed for the following files(s): {}
Error message
Comparison failed for the following files(s): {} What it means
Raised by update_directory in utilities.py when filecmp.cmpfiles reports files in the `errors` list — files that exist in both src and dst but could not be compared (os.error on stat/read, permission denied, etc.). The directory sync aborts rather than silently skipping.
Source
Thrown at src/coreclr/scripts/utilities.py:96
"""Updates dest directory with files from src directory
Args:
destpath (str): The destination path to sync with the source
srcpath (str): The source path to sync to the destination
recursive(boolean): If True, descend into and update subdirectories (default: True)
destructive(boolean): If True, delete files in the destination which do not exist in the source (default: True)
shallow(boolean): If True, only use os.stat to diff files. Do not examine contents (default: False)
"""
srcfiles, srcdirs = split_entries(os.listdir(srcpath), srcpath)
dstfiles, dstdirs = split_entries(os.listdir(dstpath), dstpath)
# Update files in both src and destination which are different in destination
commonfiles = srcfiles.intersection(dstfiles)
_, mismatches, errors = filecmp.cmpfiles(srcpath, dstpath, commonfiles, shallow=shallow)
if errors:
raise RuntimeError("Comparison failed for the following files(s): {}".format(errors))
for mismatch in mismatches:
shutil.copyfile(os.path.join(srcpath, mismatch), os.path.join(dstpath, mismatch))
# Copy over files from source which do not exist in the destination
for missingfile in srcfiles.difference(dstfiles):
shutil.copyfile(os.path.join(srcpath, missingfile), os.path.join(dstpath, missingfile))
#If destructive, delete files in destination which do not exist in sourc
if destructive:
for deadfile in dstfiles.difference(srcfiles):
print(deadfile)
os.remove(os.path.join(dstpath, deadfile))
for deaddir in dstdirs.difference(srcdirs):
print(deaddir)
shutil.rmtree(os.path.join(dstpath, deaddir))
View on GitHub (pinned to 290d5ab72c)
Solutions
- Inspect the files in the error list for locks/permissions: `ls -l` and `stat` each.
- Close any process holding the files (or disable AV locking) and rerun.
- Fix permissions: `chmod -R u+rw <dst>` (or the offending side).
- If a file is genuinely corrupt/unreadable, remove it from dst so update_directory copies it fresh.
Example fix
// before # update_directory raises [197] with ['coreclr.dll'] // after chmod u+rw <dst>/coreclr.dll # or rm it; rerun update_directory
Defensive patterns
Strategy: validation
Validate before calling
import os, stat
for f in commonfiles:
for side in (srcpath, dstpath):
p = os.path.join(side, f)
if not os.access(p, os.R_OK):
raise SystemExit(f'{p} not readable; fix perms before update_directory') Type guard
def all_commonfiles_readable(commonfiles, srcpath, dstpath) -> bool:
import os
return all(os.access(os.path.join(s,f), os.R_OK) for f in commonfiles for s in (srcpath,dstpath)) Try / catch
try:
update_directory(src, dst)
except RuntimeError as e:
if 'Comparison failed' in str(e):
import re; files = re.findall(r"'([^']+)'", str(e))
for f in files: os.chmod(os.path.join(dst,f), 0o644)
update_directory(src, dst) Prevention
- Ensure dst is writable and not locked before sync
- Close processes holding files on Windows
- Run syncs from an account with full perms
When it happens
Trigger: A common file exists in src and dst but filecmp cannot stat or open it (EACCES, EIO, file locked on Windows, symlink loop, transient FS error).
Common situations: Windows file lock on a DLL being written; read-only permissions on dst; broken symlinks; network-mounted artifact dir with intermittent errors; antivirus locking the file mid-compare.
Related errors
- NotImplementedException
- Invalid Entry {line}in {exclusion_filename}
- Invalid Entry {line}in {inclusion_filename}
- Problem launching createdump (may not have execute permissio
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/64e340a84c1c0cbd.
Report an issue: GitHub.