{"record":{"id":"8006b2b69e08c95d","repo":"angular/angular-cli","slug":"path-json-stringify-path-must-be-absolute","errorCode":null,"errorMessage":"Path ${JSON.stringify(path)} must be absolute.","messagePattern":"Path (.+?) must be absolute\\.","errorType":"exception","errorClass":"PathMustBeAbsoluteException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/core/src/virtual-fs/path.ts","lineNumber":131,"sourceCode":"  } else {\n    return p1;\n  }\n}\n\n/**\n * Returns true if a path is absolute.\n */\nexport function isAbsolute(p: Path): boolean {\n  return p.startsWith(NormalizedSep);\n}\n\n/**\n * Returns a path such that `join(from, relative(from, to)) == to`.\n * Both paths must be absolute, otherwise it does not make much sense.\n */\nexport function relative(from: Path, to: Path): Path {\n  if (!isAbsolute(from)) {\n    throw new PathMustBeAbsoluteException(from);\n  }\n  if (!isAbsolute(to)) {\n    throw new PathMustBeAbsoluteException(to);\n  }\n\n  let p: string;\n\n  if (from == to) {\n    p = '';\n  } else {\n    const splitFrom = split(from);\n    const splitTo = split(to);\n\n    while (splitFrom.length > 0 && splitTo.length > 0 && splitFrom[0] == splitTo[0]) {\n      splitFrom.shift();\n      splitTo.shift();\n    }\n","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/core/src/virtual-fs/path.ts#L113-L149","documentation":"The virtual-fs relative(from, to) function computes a path such that join(from, relative(from, to)) === to. It only makes sense for absolute normalized paths, so it throws PathMustBeAbsoluteException when the `from` argument is relative. Normalized virtual paths must start with '/' (the NormalizedRoot).","triggerScenarios":"Calling relative() with a `from` path that does not start with '/' — e.g. a fragment like 'src/app', './src', or a raw OS path like 'C:\\\\project' or a Windows backslash path not normalized to '/c/project'.","commonSituations":"Mixing PathFragment values (file names) with full Path values; passing unnormalized process.cwd() or user-supplied relative paths into virtual-fs utilities; forgetting to use normalize() or resolve() before calling relative().","solutions":["Ensure the from path is absolute: call resolve('/') or join(NormalizedRoot, path) before passing it to relative()","Normalize the input with normalize(path) so separators and root are correct","Check with isAbsolute(path) and throw/handle your own error with a clearer message upstream"],"exampleFix":"// before\nconst rel = relative(path.basename(fullPath), targetPath); // from is a fragment\n// after\nconst rel = relative(normalize(fullPath), normalize(targetPath));","handlingStrategy":"validation","validationCode":"import { relative, isAbsolute, normalize, Path } from '@angular-devkit/core';\nfunction safeRelative(from: string, to: string): Path {\n  const f = normalize(from), t = normalize(to);\n  if (!isAbsolute(f)) throw new Error(`'from' must be absolute: ${from}`);\n  if (!isAbsolute(t)) throw new Error(`'to' must be absolute: ${to}`);\n  return relative(f, t);\n}","typeGuard":"import { isAbsolute, Path } from '@angular-devkit/core';\nfunction isAbsolutePath(p: Path): p is Path {\n  return typeof p === 'string' && p.startsWith('/') && isAbsolute(p);\n}","tryCatchPattern":"try {\n  return relative(from, to);\n} catch (e) {\n  if (/must be absolute/.test(e.message)) {\n    return relative(normalize(resolve('/', from)), normalize(resolve('/', to)));\n  }\n  throw e;\n}","preventionTips":["Always normalize external input with normalize() before path math","Never pass PathFragment values where a full Path is required","Check isAbsolute() on both arguments before calling relative()","Convert OS paths (e.g. Windows) to normalized virtual-fs paths first"],"tags":["angular-devkit","virtual-fs","path","absolute-path"],"backgroundTag":"path-must-be-absolute","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}