angular/angular-cli · error · MergeConflictException

A merge conflicted on path "${path}".

Error message

A merge conflicted on path "${path}".

What it means

MergeConflictException from HostTree.merge is thrown when merging a tree whose actions include a Create ('c') for a path that already exists in the target tree, unless creationConflictAllowed was set. Two trees both creating the same file is treated as a conflict because the sink would reject the second create anyway.

Source

Thrown at packages/angular_devkit/schematics/src/tree/host-tree.ts:211

    const overwriteConflictAllowed =
      (strategy & MergeStrategy.AllowOverwriteConflict) == MergeStrategy.AllowOverwriteConflict;
    const deleteConflictAllowed =
      (strategy & MergeStrategy.AllowDeleteConflict) == MergeStrategy.AllowDeleteConflict;

    other.actions.forEach((action) => {
      switch (action.kind) {
        case 'c': {
          const { path, content } = action;

          if (this._willCreate(path) || this._willOverwrite(path) || this.exists(path)) {
            const existingContent = this.read(path);
            if (existingContent && content.equals(existingContent)) {
              // Identical outcome; no action required
              return;
            }

            if (!creationConflictAllowed) {
              throw new MergeConflictException(path);
            }

            this._record.overwrite(path, content as {} as virtualFs.FileBuffer).subscribe();
          } else {
            this._record.create(path, content as {} as virtualFs.FileBuffer).subscribe();
          }

          return;
        }

        case 'o': {
          const { path, content } = action;
          if (this._willDelete(path) && !overwriteConflictAllowed) {
            throw new MergeConflictException(path);
          }

          // Ignore if content is the same (considered the same change).
          if (this._willOverwrite(path)) {

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Pass { creationConflictAllowed: true } to merge() if overwriting the existing file is intended.
  2. Ensure only one tree creates the file; convert the second side to an overwrite action.
  3. Stagger or namespace generated file paths so the two trees create different files.
  4. Delete the pre-existing file from the target tree before merging.

Example fix

// before
host.merge(other); // throws on duplicate creates
// after
host.merge(other, { creationConflictAllowed: true });
Defensive patterns

Strategy: try-catch

Validate before calling

const conflicts: string[] = [];
other.actions.forEach((a) => { if (a.kind === 'c' && tree.exists(a.path)) conflicts.push(a.path); });
if (conflicts.length) { /* resolve or set creationConflictAllowed */ }

Type guard

null

Try / catch

try { host.merge(other); } catch (e) { if (e instanceof MergeConflictException) { host.merge(other, { creationConflictAllowed: true }); } else { throw e; } }

Prevention

When it happens

Trigger: tree.merge(other) or branch merging where `other` contains a create action for a path already present in `this`, and options.creationConflictAllowed is not true.

Common situations: Composing schematics that each generate the same new file (e.g. both add a README or config); applying a partial schematic to a tree that already staged the same file; re-running generation into a branched tree.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/b2759e5afdc3c62f. Report an issue: GitHub.