{"record":{"id":"b7b593a50f58efad","repo":"evanw/esbuild","slug":"output-directory-q-must-be-contained-in-serve-dir","errorCode":null,"errorMessage":"Output directory %q must be contained in serve directory %q","messagePattern":"Output directory %q must be contained in serve directory %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/api/serve_other.go","lineNumber":813,"sourceCode":"\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\n\tnetwork := \"tcp4\"\n\thost := \"0.0.0.0\"\n\thostIsIP := true\n\tif serveOptions.Host != \"\" {\n\t\thost = serveOptions.Host","sourceCodeStart":795,"sourceCodeEnd":831,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/pkg/api/serve_other.go#L795-L831","documentation":"When both servedir and outdir are specified, the output directory must be contained within the serve directory. This error fires when the computed relative path from servedir to outdir starts with '..' (i.e. outdir is outside servedir), because the serve mode would not be able to serve the build output.","triggerScenarios":"Setting outdir to a path that is a sibling or ancestor of servedir rather than a descendant, e.g. servedir='./public' and outdir='../build'.","commonSituations":"Misconfiguring the directory relationship, common when migrating from a non-serve build setup where outdir was set independently of servedir.","solutions":["Set outdir to be a subdirectory of servedir","Alternatively, set servedir to a parent directory that contains outdir","Ensure the relative path from servedir to outdir does not start with '..'"],"exampleFix":"// before\nesbuild.serve({ servedir: 'public' }) // outdir: '../build'\n// after\nesbuild.serve({ servedir: 'public' }) // outdir: 'public/build'","handlingStrategy":"validation","validationCode":"import path from 'path'\nfunction validateOutdirContained(servedir, outdir) {\n  const rel = path.relative(path.resolve(servedir), path.resolve(outdir))\n  if (rel === '..' || rel.startsWith('..')) {\n    throw new Error(`outdir must be inside servedir, but relative path is: ${rel}`)\n  }\n}\nvalidateOutdirContained(serveOptions.servedir, buildOptions.outdir)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure outdir is a subdirectory of servedir","Use path.relative() to verify the relationship before starting serve","Set servedir to a common parent if outdir cannot be moved"],"tags":["esbuild","serve","filesystem","path","config"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}