{"id":"4d665f392fe1ee76","repo":"evanw/esbuild","slug":"rel-can-t-make-targpath-relative-to-basepath","errorCode":null,"errorMessage":"Rel: can't make {targpath} relative to {basepath}","messagePattern":"Rel: can't make (.+?) relative to (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/fs/filepath.go","lineNumber":593,"sourceCode":"// Rel calls Clean on the result.\nfunc (fp goFilepath) rel(basepath, targpath string) (string, error) {\n\tbaseVol := fp.volumeName(basepath)\n\ttargVol := fp.volumeName(targpath)\n\tbase := fp.clean(basepath)\n\ttarg := fp.clean(targpath)\n\tif fp.sameWord(targ, base) {\n\t\treturn \".\", nil\n\t}\n\tbase = base[len(baseVol):]\n\ttarg = targ[len(targVol):]\n\tif base == \".\" {\n\t\tbase = \"\"\n\t}\n\t// Can't use IsAbs - `\\a` and `a` are both relative in Windows.\n\tbaseSlashed := len(base) > 0 && base[0] == fp.pathSeparator\n\ttargSlashed := len(targ) > 0 && targ[0] == fp.pathSeparator\n\tif baseSlashed != targSlashed || !fp.sameWord(baseVol, targVol) {\n\t\treturn \"\", errors.New(\"Rel: can't make \" + targpath + \" relative to \" + basepath)\n\t}\n\t// Position base[b0:bi] and targ[t0:ti] at the first differing elements.\n\tbl := len(base)\n\ttl := len(targ)\n\tvar b0, bi, t0, ti int\n\tfor {\n\t\tfor bi < bl && base[bi] != fp.pathSeparator {\n\t\t\tbi++\n\t\t}\n\t\tfor ti < tl && targ[ti] != fp.pathSeparator {\n\t\t\tti++\n\t\t}\n\t\tif !fp.sameWord(targ[t0:ti], base[b0:bi]) {\n\t\t\tbreak\n\t\t}\n\t\tif bi < bl {\n\t\t\tbi++\n\t\t}","sourceCodeStart":575,"sourceCodeEnd":611,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/internal/fs/filepath.go#L575-L611","documentation":"esbuild vendors filepath.Rel in internal/fs/filepath.go. This branch returns the error when Rel cannot relate targpath to basepath because the two paths are on different volumes (e.g. different Windows drive letters C: vs D:) or one is volume-rooted/absolute-slashed and the other is not. Rel fundamentally requires both paths to share a volume and rootedness.","triggerScenarios":"rel(basepath, targpath) is called where baseVol != targVol (different drive letters / UNC hosts) or where one path begins with a path separator and the other does not (baseSlashed != targSlashed). In esbuild this surfaces from computeRelativePath when the output directory and serve directory live on different volumes, or from watch-file relativization across drives.","commonSituations":"On Windows, outdir on D:\\ while servedir is on C:\\ (or vice versa); mixing a UNC path (\\\\server\\share) with a drive path; one path passed as relative (no leading slash) while the other is absolute; cross-volume builds where the project and build output are on different mounts.","solutions":["Ensure both paths are on the same volume/drive (e.g. move outdir under the same drive as servedir).","Pass absolute paths consistently to both arguments so rootedness matches.","On Windows, normalize drive letters / UNC prefixes so they match between the two paths.","If using esbuild serve, keep AbsOutputDir and Servedir on the same filesystem root."],"exampleFix":"// before (Windows, cross-volume)\nctx.Serve({ Servedir: \"C:\\\\www\", /* outdir = D:\\\\build\" })\n\n// after (same volume)\nctx.Serve({ Servedir: \"C:\\\\www\", /* outdir = C:\\\\www\\\\build\" })","handlingStrategy":"validation","validationCode":"const path = require('path');\nfunction sameVolume(a, b) {\n  const ra = path.resolve(a), rb = path.resolve(b);\n  // Windows: compare drive letter / UNC root\n  return ra.split(path.sep)[0].toLowerCase() === rb.split(path.sep)[0].toLowerCase();\n}\nif (!sameVolume(servedir, outdir)) throw new Error('cross-volume paths');","typeGuard":null,"tryCatchPattern":"try { await ctx.Serve({ Servedir, /* outdir set */ }); } catch (e) { if (/can't make .* relative to/.test(e.message)) { /* move outdir onto same volume as servedir */ } throw e; }","preventionTips":["Keep outdir and servedir on the same drive/volume.","Pass absolute paths consistently.","On Windows, normalize drive letters and UNC prefixes.","Validate volume equality before calling Serve()."],"tags":["esbuild","filesystem","path-resolution","windows","cross-volume"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}