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
- Verify the fallback file path exists and is readable before starting serve mode
- Use an absolute path for the fallback file
- 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
- Check that the fallback file exists and is readable before starting serve mode
- Resolve the fallback path to absolute before passing it
- Remove the fallback option if you do not need SPA-style routing
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
- Cannot compute relative path from
- Invalid serve path
- Output directory must be contained in serve directory
- The working directory
- Cannot serve a disposed context
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)