{"id":"248a88498d73b8bb","repo":"evanw/esbuild","slug":"cannot-compute-relative-path-from-q-to-q","errorCode":null,"errorMessage":"Cannot compute relative path from %q to %q\n","messagePattern":"Cannot compute relative path from %q to %q\n","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/api/serve_other.go","lineNumber":791,"sourceCode":"\n\t// Stuff related to the output directory only matters if there are entry points\n\toutdirPathPrefix := \"\"\n\tif len(ctx.args.entryPoints) > 0 {\n\t\t// Don't allow serving when builds are written to stdout\n\t\tif ctx.args.options.WriteToStdout {\n\t\t\twhat := \"entry points\"\n\t\t\tif len(ctx.args.entryPoints) == 1 {\n\t\t\t\twhat = \"an entry point\"\n\t\t\t}\n\t\t\treturn ServeResult{}, fmt.Errorf(\"Cannot serve %s without an output path\", what)\n\t\t}\n\n\t\t// Compute the output path prefix\n\t\tif serveOptions.Servedir != \"\" && ctx.args.options.AbsOutputDir != \"\" {\n\t\t\t// Make sure the output directory is contained in the \"servedir\" directory\n\t\t\trelPath, ok := ctx.realFS.Rel(serveOptions.Servedir, ctx.args.options.AbsOutputDir)\n\t\t\tif !ok {\n\t\t\t\treturn ServeResult{}, fmt.Errorf(\n\t\t\t\t\t\"Cannot compute relative path from %q to %q\\n\", serveOptions.Servedir, ctx.args.options.AbsOutputDir)\n\t\t\t}\n\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\") // Fix paths on Windows\n\t\t\tif relPath == \"..\" || strings.HasPrefix(relPath, \"../\") {\n\t\t\t\treturn ServeResult{}, fmt.Errorf(\n\t\t\t\t\t\"Output directory %q must be contained in serve directory %q\",\n\t\t\t\t\tprettyPrintPath(ctx.realFS, ctx.args.options.AbsOutputDir),\n\t\t\t\t\tprettyPrintPath(ctx.realFS, serveOptions.Servedir),\n\t\t\t\t)\n\t\t\t}\n\t\t\tif relPath != \".\" {\n\t\t\t\toutdirPathPrefix = relPath\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine the host\n\tvar listener net.Listener","sourceCodeStart":773,"sourceCodeEnd":809,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/pkg/api/serve_other.go#L773-L809","documentation":"Returned by internalContext.Serve when ctx.realFS.Rel(servedir, AbsOutputDir) fails (ok=false). esbuild needs to compute the output directory relative to the serve directory to correctly URL-map served files; if the filesystem layer cannot relativize the two paths (e.g. cross-volume, or a path resolution failure), it gives up with this error. This is distinct from the 'must be contained' error — here the rel computation itself failed.","triggerScenarios":"Serve() is called with a Servedir and the context has an AbsOutputDir, but realFS.Rel(Servedir, AbsOutputDir) returns ok=false. Typically because the two paths are on different volumes/drives or one cannot be canonicalized, echoing the Rel failure in internal/fs/filepath.go.","commonSituations":"On Windows, servedir on C:\\ and outdir on D:\\; one path on a network mount and the other local; a path that fails to absolutize (nonexistent dir) feeding into Rel; cross-device builds where output is written to a separate mount.","solutions":["Place the output directory on the same volume/drive as the serve directory.","Verify both Servedir and outdir exist and are absolute before calling Serve().","On Windows, match drive letters / UNC hosts for both paths.","If outdir is auto-derived, override it to live under servedir."],"exampleFix":"// before (cross-volume)\nctx.Serve({ Servedir: '/mnt/www' }); // outdir on /dev/shm/build\n\n// after (same volume)\nmv /dev/shm/build /mnt/www/build   // or set outdir under servedir\nctx = await api.Context({ ..., outdir: '/mnt/www/build' });\nctx.Serve({ Servedir: '/mnt/www' });","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nfunction sameVolume(a, b) { /* compare volume root of resolved paths */ }\nif (Servedir && outdir && !sameVolume(Servedir, outdir)) throw new Error('cross-volume');","typeGuard":null,"tryCatchPattern":"try { await ctx.Serve({ Servedir }); } catch (e) { if (/Cannot compute relative path/.test(e.message)) { /* move outdir under servedir, same volume */ } throw e; }","preventionTips":["Keep outdir and servedir on the same volume.","Ensure both paths exist and are absolute.","On Windows, match drive letters / UNC hosts.","Validate path relativization before Serve()."],"tags":["esbuild","serve","path-resolution","cross-volume","configuration"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}