angular/angular-cli · error · PathCannotBeFragmentException

Path ${JSON.stringify(path)} cannot be made a fragment.

Error message

Path ${JSON.stringify(path)} cannot be made a fragment.

What it means

fragment(path) converts a string into a PathFragment, which by definition is a single path segment containing no separator. If the string contains NormalizedSep ('/'), it cannot be a fragment and fragment() throws PathCannotBeFragmentException.

Source

Thrown at packages/angular_devkit/core/src/virtual-fs/path.ts:177

  return normalize(p);
}

/**
 * Returns a Path that is the resolution of p2, from p1. If p2 is absolute, it will return p2,
 * otherwise will join both p1 and p2.
 */
export function resolve(p1: Path, p2: Path): Path {
  if (isAbsolute(p2)) {
    return p2;
  } else {
    return join(p1, p2);
  }
}

export function fragment(path: string): PathFragment {
  if (path.indexOf(NormalizedSep) != -1) {
    throw new PathCannotBeFragmentException(path);
  }

  return path as PathFragment;
}

/**
 * normalize() cache to reduce computation. For now this grows and we never flush it, but in the
 * future we might want to add a few cache flush to prevent this from growing too large.
 */
let normalizedCache = new Map<string, Path>();

/**
 * Reset the cache. This is only useful for testing.
 * @private
 */
export function resetNormalizeCache(): void {
  normalizedCache = new Map<string, Path>();
}

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Use normalize() or join() instead of fragment() when the value may contain separators
  2. Strip to the last segment first: fragment(path.split('/').pop()) or use basename(fullPath) which is designed for full paths
  3. Validate indexOf('/') === -1 before calling fragment()

Example fix

// before
const name = fragment('src/app/main.ts'); // throws
// after
const name = basename('src/app/main.ts' as Path); // 'main.ts'
Defensive patterns

Strategy: validation

Validate before calling

import { fragment, PathFragment } from '@angular-devkit/core';
function safeFragment(s: string): PathFragment {
  if (s.includes('/')) {
    throw new Error(`'${s}' is not a single path segment; use basename() instead`);
  }
  return fragment(s);
}

Type guard

function isFragmentCandidate(s: string): boolean {
  return typeof s === 'string' && s.length > 0 && !s.includes('/');
}

Try / catch

try {
  const frag = fragment(input);
} catch (e) {
  if (/cannot be made a fragment/.test(e.message)) {
    const frag = basename(input as Path); // extract last segment instead
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling fragment('src/app') or fragment('/abs/path') — any string containing '/'; also calling basename() or fragments() with input that unexpectedly contains separators.

Common situations: Trying to use fragment() to create a full path (use normalize()/join() instead); passing a full path where only the last segment is wanted; multi-segment extensions like 'file.spec.ts' are fine, but 'dir/file.ts' is not.

Related errors


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