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
- Use normalize() or join() instead of fragment() when the value may contain separators
- Strip to the last segment first: fragment(path.split('/').pop()) or use basename(fullPath) which is designed for full paths
- 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
- Only pass single path segments to fragment(); use normalize()/join() for full paths
- Use basename() when you need the last segment of a full path
- Watch for hidden separators from user input or template interpolation
- Remember multi-dot names ('file.spec.ts') are valid fragments; only '/' disqualifies
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
- Path is a directory.
- Path is a file.
- Path ${JSON.stringify(path)} must be absolute.
- File does not exist.
- File already exist.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/d332fa709e597874.
Report an issue: GitHub.