{"record":{"id":"d332fa709e597874","repo":"angular/angular-cli","slug":"path-json-stringify-path-cannot-be-made-a-frag","errorCode":null,"errorMessage":"Path ${JSON.stringify(path)} cannot be made a fragment.","messagePattern":"Path (.+?) cannot be made a fragment\\.","errorType":"exception","errorClass":"PathCannotBeFragmentException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/core/src/virtual-fs/path.ts","lineNumber":177,"sourceCode":"\n  return normalize(p);\n}\n\n/**\n * Returns a Path that is the resolution of p2, from p1. If p2 is absolute, it will return p2,\n * otherwise will join both p1 and p2.\n */\nexport function resolve(p1: Path, p2: Path): Path {\n  if (isAbsolute(p2)) {\n    return p2;\n  } else {\n    return join(p1, p2);\n  }\n}\n\nexport function fragment(path: string): PathFragment {\n  if (path.indexOf(NormalizedSep) != -1) {\n    throw new PathCannotBeFragmentException(path);\n  }\n\n  return path as PathFragment;\n}\n\n/**\n * normalize() cache to reduce computation. For now this grows and we never flush it, but in the\n * future we might want to add a few cache flush to prevent this from growing too large.\n */\nlet normalizedCache = new Map<string, Path>();\n\n/**\n * Reset the cache. This is only useful for testing.\n * @private\n */\nexport function resetNormalizeCache(): void {\n  normalizedCache = new Map<string, Path>();\n}","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/core/src/virtual-fs/path.ts#L159-L195","documentation":"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.","triggerScenarios":"Calling fragment('src/app') or fragment('/abs/path') — any string containing '/'; also calling basename() or fragments() with input that unexpectedly contains separators.","commonSituations":"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.","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()"],"exampleFix":"// before\nconst name = fragment('src/app/main.ts'); // throws\n// after\nconst name = basename('src/app/main.ts' as Path); // 'main.ts'","handlingStrategy":"validation","validationCode":"import { fragment, PathFragment } from '@angular-devkit/core';\nfunction safeFragment(s: string): PathFragment {\n  if (s.includes('/')) {\n    throw new Error(`'${s}' is not a single path segment; use basename() instead`);\n  }\n  return fragment(s);\n}","typeGuard":"function isFragmentCandidate(s: string): boolean {\n  return typeof s === 'string' && s.length > 0 && !s.includes('/');\n}","tryCatchPattern":"try {\n  const frag = fragment(input);\n} catch (e) {\n  if (/cannot be made a fragment/.test(e.message)) {\n    const frag = basename(input as Path); // extract last segment instead\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["angular-devkit","virtual-fs","path","pathfragment"],"backgroundTag":"path-cannot-be-fragment","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}