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

  1. Remove or rename the duplicated patch in one of the source directories
  2. Drop the duplicate source directory from the source_iter list
  3. Namespace patch paths per source (e.g. put patches under a platform-specific subdirectory) so relative paths are unique
  4. 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

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


AI-assisted analysis of ungoogled-software/ungoogled-chromium@f85e84a480 (2026-08-29). Data as JSON: /api/errors/de0b90b56728de8e. Report an issue: GitHub.