evanw/esbuild · error

Invalid fallback path

Error message

Invalid fallback path: %s

What it means

The fallback option for serve mode (the file served when no route matches) must be resolvable to an absolute path. This error fires when ctx.realFS.Abs(serveOptions.Fallback) fails.

Solutions

  1. Verify the fallback file path exists and is readable before starting serve mode
  2. Use an absolute path for the fallback file
  3. Remove the fallback option if you do not need SPA-style fallback routing

Example fix

// before
esbuild.serve({ servedir: '.', fallback: './missing.html' })
// after
esbuild.serve({ servedir: '.', fallback: path.resolve('./public/404.html') })
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs'
import path from 'path'
function validateFallback(fallback) {
  if (!fallback) return ''
  const abs = path.resolve(fallback)
  if (!fs.existsSync(abs) || !fs.statSync(abs).isFile()) {
    throw new Error(`fallback file does not exist: ${abs}`)
  }
  return abs
}
serveOptions.fallback = validateFallback(serveOptions.fallback)

Prevention

When it happens

Trigger: Passing a fallback file path that does not exist or cannot be resolved to an absolute path.

Common situations: Pointing fallback to a deleted or renamed file (e.g. 'index.html' moved to '404.html'), a typo'd path, or a path with permission issues.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/b96635d04d122a1e. Report an issue: GitHub.

Appendix: source

Thrown at pkg/api/serve_other.go:780

	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)
		}
	}

	// Stuff related to the output directory only matters if there are entry points
	outdirPathPrefix := ""
	if len(ctx.args.entryPoints) > 0 {
		// Don't allow serving when builds are written to stdout
		if ctx.args.options.WriteToStdout {
			what := "entry points"
			if len(ctx.args.entryPoints) == 1 {
				what = "an entry point"

View on GitHub (pinned to f6058f8364)