ungoogled-software/ungoogled-chromium · error · FileExistsError
Patches from {source_dir} have conflicting paths with other
Error message
Patches from {source_dir} have conflicting paths with other sources: {patch_intersection} What it means
merge_patches raises FileExistsError when two source patch directories contain patch files at the same relative path (per their series files). Overlapping patches would silently overwrite each other during copy, so the merge aborts and lists the conflicting paths.
Source
Thrown at utils/patches.py:178
destination must not already exist, unless prepend is True. If prepend is True, then
the source patches will be prepended to the destination.
"""
series = []
known_paths = set()
if destination.exists():
if prepend:
if not (destination / 'series').exists():
raise FileNotFoundError(
f"Could not find series file in existing destination: {destination / 'series'}")
known_paths.update(generate_patches_from_series(destination))
else:
raise FileExistsError(f'destination already exists: {destination}')
for source_dir in source_iter:
patch_paths = tuple(generate_patches_from_series(source_dir))
patch_intersection = known_paths.intersection(patch_paths)
if patch_intersection:
raise FileExistsError(f'Patches from {source_dir} have conflicting paths '
f'with other sources: {patch_intersection}')
series.extend(patch_paths)
_copy_files(patch_paths, source_dir, destination)
if prepend and (destination / 'series').exists():
series.extend(generate_patches_from_series(destination))
with (destination / 'series').open('w') as series_file:
series_file.write('\n'.join(map(str, series)))
def _apply_callback(args, parser_error):
logger = get_logger()
patch_bin_path = None
if args.patch_bin is not None:
patch_bin_path = Path(args.patch_bin)
if not patch_bin_path.exists():
patch_bin_path = shutil.which(args.patch_bin)
if patch_bin_path:
patch_bin_path = Path(patch_bin_path)View on GitHub (pinned to f85e84a480)
Solutions
- Remove or rename the duplicated patch in one of the source directories
- Drop the duplicate source directory from the source_iter list
- Namespace patch paths per source (e.g. put patches under a platform-specific subdirectory) so relative paths are unique
- Diff the series files of the sources to identify and reconcile the overlapping entries before merging
Example fix
# before sources = [platform_a_patches, platform_b_patches] # both contain common/0001-fix.patch merge_patches(sources, dest) # after sources = [platform_a_patches, platform_b_patches] # rename one side: platform_b_patches/common/0001-fix.patch -> platform_b_patches/b/0001-fix.patch merge_patches(sources, dest)
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
from utils.patches import generate_patches_from_series
seen = set()
for src in source_dirs:
paths = set(generate_patches_from_series(Path(src)))
dupes = seen & paths
assert not dupes, f'conflicting patch paths across sources: {dupes}'
seen |= paths Type guard
def sources_are_disjoint(source_dirs):
seen = set()
for src in source_dirs:
paths = set(generate_patches_from_series(Path(src)))
if seen & paths:
return False
seen |= paths
return True Try / catch
try:
merge_patches(sources, dest)
except FileExistsError as e:
logger.error('conflicting patch paths: %s', e)
# inspect e for the listed intersection and de-duplicate sources before retrying Prevention
- Namespace each source's patches under a unique subdirectory
- Keep a single source of truth for shared/common patches
- Deduplicate source_dirs before merging
- Diff series files across sources in CI to catch overlaps early
When it happens
Trigger: Calling merge_patches / merge_platform_patches where generate_patches_from_series(source_dir) for two different source_dirs yields identical patch paths; also when prepending into an existing destination whose series already lists the same patch names as an incoming source.
Common situations: Merging two platform patch sets that both vendor a common patch (e.g. 'fix-common/0001-base.patch'); including the same source directory twice in sources; upstream refactor renamed dirs so distinct patches now share filenames.
Related errors
- destination already exists: {destination}
- FileExistsError
- Could not find series file in existing destination: {destina
AI-assisted analysis of ungoogled-software/ungoogled-chromium@f85e84a480 (2026-08-29).
Data as JSON: /api/errors/de0b90b56728de8e.
Report an issue: GitHub.