{"id":"2a021f9b41b7cd5c","repo":"evanw/esbuild","slug":"cannot-serve-s-without-an-output-path","errorCode":null,"errorMessage":"Cannot serve %s without an output path","messagePattern":"Cannot serve (.+?) without an output path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/api/serve_other.go","lineNumber":783,"sourceCode":"\t}\n\n\t// Validate the CORS origins\n\tfor _, origin := range serveOptions.CORS.Origin {\n\t\tif star := strings.IndexByte(origin, '*'); star >= 0 && strings.ContainsRune(origin[star+1:], '*') {\n\t\t\treturn ServeResult{}, fmt.Errorf(\"Invalid origin: %s\", origin)\n\t\t}\n\t}\n\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}","sourceCodeStart":765,"sourceCodeEnd":801,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/pkg/api/serve_other.go#L765-L801","documentation":"Returned by internalContext.Serve when the build has entry points but options.WriteToStdout is true. Serving requires writing build output to actual files on disk so the HTTP server can serve them; writing to stdout produces no files. esbuild detects entry points + WriteToStdout and refuses to serve, since there would be nothing to serve. The message names 'an entry point' (singular) or 'entry points' (plural).","triggerScenarios":"A context configured with entry points and WriteToStdout:true (e.g. from --log-plugin or a stdout output config), then ctx.Serve() is called. The check at serve_other.go:778 sees WriteToStdout and returns the error.","commonSituations":"Configuring esbuild to emit to stdout (sometimes done for piping) and also trying to run serve mode; leftover WriteToStdout:true from a different use case; a wrapper that sets stdout output and then starts a dev server.","solutions":["Disable WriteToStdout when using serve mode — set an outdir or outfile instead.","If you need both behaviors, use two separate esbuild contexts.","Check your config for stdout output flags before calling Serve().","Ensure options.Write is true and an outdir is set for served builds."],"exampleFix":"// before\nctx = await api.Context({ entryPoints: ['src/index.js'], write: false, stdout: true });\nctx.Serve({ servedir: './www' }); // -> Cannot serve ... without an output path\n\n// after\nctx = await api.Context({ entryPoints: ['src/index.js'], outdir: './www', write: true });\nctx.Serve({ servedir: './www' });","handlingStrategy":"validation","validationCode":"if (opts.entryPoints?.length && opts.writeToStdout) {\n  throw new Error('Cannot serve with stdout output; set outdir instead');\n}","typeGuard":"function isStdoutServeError(e) { return /Cannot serve .* without an output path/.test(e?.message || ''); }","tryCatchPattern":"try { await ctx.Serve(opts); } catch (e) { if (isStdoutServeError(e)) { delete opts.writeToStdout; opts.outdir = './dist'; /* recreate context */ } throw e; }","preventionTips":["Never combine WriteToStdout with serve mode.","Set outdir/outfile for served builds.","Use separate contexts for stdout-piping vs serving.","Validate output config before Serve()."],"tags":["esbuild","serve","configuration","stdout","output"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}