evanw/esbuild · error

Invalid serve path: %s

Error message

Invalid serve path: %s

What it means

Returned by internalContext.Serve when serveOptions.Servedir is non-empty but ctx.realFS.Abs(Servedir) fails to produce an absolute path. esbuild needs an absolute, canonical servedir to map incoming request URLs to files; if the filesystem layer cannot absolutize the path (it doesn't exist or can't be resolved), Serve rejects it. The Abs failure returns ok=false.

Source

Thrown at pkg/api/serve_other.go:754

		return ServeResult{}, errors.New("Cannot serve a disposed context")
	}

	// Don't allow starting serve mode multiple times
	if ctx.handler != nil {
		return ServeResult{}, errors.New("Serve mode has already been enabled")
	}

	// Don't allow starting serve mode multiple times
	if (serveOptions.Keyfile != "") != (serveOptions.Certfile != "") {
		return ServeResult{}, errors.New("Must specify both key and certificate for HTTPS")
	}

	// Validate the "servedir" path
	if serveOptions.Servedir != "" {
		if absPath, ok := ctx.realFS.Abs(serveOptions.Servedir); ok {
			serveOptions.Servedir = absPath
		} else {
			return ServeResult{}, fmt.Errorf("Invalid serve path: %s", serveOptions.Servedir)
		}
	}

	// Validate the "fallback" path
	if serveOptions.Fallback != "" {
		if absPath, ok := ctx.realFS.Abs(serveOptions.Fallback); ok {
			serveOptions.Fallback = absPath
		} else {
			return ServeResult{}, fmt.Errorf("Invalid fallback path: %s", serveOptions.Fallback)
		}
	}

	// Validate the CORS origins
	for _, origin := range serveOptions.CORS.Origin {
		if star := strings.IndexByte(origin, '*'); star >= 0 && strings.ContainsRune(origin[star+1:], '*') {
			return ServeResult{}, fmt.Errorf("Invalid origin: %s", origin)
		}
	}

View on GitHub (pinned to 6ff1d8b0d8)

Solutions

  1. Create the servedir directory before calling Serve().
  2. Verify the path: pass an absolute path or ensure the relative path resolves from esbuild's cwd.

Example fix

// before
ctx.Serve({ Servedir: './public' }); // ./public doesn't exist -> Invalid serve path

// after
const fs = require('fs');
fs.mkdirSync('./public', { recursive: true });
ctx.Serve({ Servedir: path.resolve('./public') });
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const abs = path.resolve(serveOpts.Servedir);
if (!fs.existsSync(abs) || !fs.statSync(abs).isDirectory()) throw new Error('servedir missing');
serveOpts.Servedir = abs;

Type guard

function isServePathError(e) { return /Invalid serve path/.test(e?.message || ''); }

Try / catch

try { await ctx.Serve({ Servedir }); } catch (e) { if (isServePathError(e)) { fs.mkdirSync(Servedir, { recursive: true }); /* retry */ } throw e; }

Prevention

When it happens

Trigger: Calling ctx.Serve({ Servedir: './public' }) where './public' does not exist or cannot be resolved to an absolute path by esbuild's realFS.Abs. The ok check at serve_other.go:751 fails, yielding the error.

Common situations: The servedir directory doesn't exist yet (typo, not created); running esbuild from the wrong cwd so the relative path misses; a deployment where the static dir is at a different path than locally; permission issues preventing path resolution.

Related errors


AI-assisted analysis of evanw/esbuild@6ff1d8b0d8 (2026-08-03). Data as JSON: /data/errors/0ba51709a6ce8617.json. Report an issue: GitHub.