evanw/esbuild · error

The working directory %q is not an absolute path

Error message

The working directory %q is not an absolute path

What it means

Returned by fs.RealFS when the build/run options supply an AbsWorkingDir that is non-empty but not an absolute path. esbuild requires an absolute working directory because all file resolution, module identity, and relative error-message paths are derived from it. The check uses isAbs which honours the platform path separator (Windows drive roots vs POSIX leading '/').

Source

Thrown at internal/fs/fs_real.go:86

		fp.isWindows = true
		fp.pathSeparator = '\\'
	} else {
		fp.isWindows = false
		fp.pathSeparator = '/'
	}

	// Come up with a default working directory if one was not specified
	fp.cwd = options.AbsWorkingDir
	if fp.cwd == "" {
		if cwd, err := os.Getwd(); err == nil {
			fp.cwd = cwd
		} else if fp.isWindows {
			fp.cwd = "C:\\"
		} else {
			fp.cwd = "/"
		}
	} else if !fp.isAbs(fp.cwd) {
		return nil, fmt.Errorf("The working directory %q is not an absolute path", fp.cwd)
	}

	// Resolve symlinks in the current working directory. Symlinks are resolved
	// when input file paths are converted to absolute paths because we need to
	// recognize an input file as unique even if it has multiple symlinks
	// pointing to it. The build will generate relative paths from the current
	// working directory to the absolute input file paths for error messages,
	// so the current working directory should be processed the same way. Not
	// doing this causes test failures with esbuild when run from inside a
	// symlinked directory.
	//
	// This deliberately ignores errors due to e.g. infinite loops. If there is
	// an error, we will just use the original working directory and likely
	// encounter an error later anyway. And if we don't encounter an error
	// later, then the current working directory didn't even matter and the
	// error is unimportant.
	if path, err := fp.evalSymlinks(fp.cwd); err == nil {
		fp.cwd = path

View on GitHub (pinned to 6ff1d8b0d8)

Solutions

  1. Resolve the path to absolute before passing it: use path.resolve (JS) or filepath.Abs (Go).
  2. Omit AbsWorkingDir entirely to let esbuild use the current working directory.
  3. On Windows, ensure the path includes a drive letter and backslashes, e.g. C:\\project\\src.
  4. Log the value of AbsWorkingDir right before the build call to catch stray relative inputs.

Example fix

// before
import * as esbuild from 'esbuild'
esbuild.build({ absWorkingDir: './src', ... })

// after
import * as path from 'path'
esbuild.build({ absWorkingDir: path.resolve('./src'), ... })
Defensive patterns

Strategy: validation

Validate before calling

import * as path from 'path'
function resolveAbsWorkingDir(input) {
  if (!input) return process.cwd()
  const abs = path.isAbsolute(input) ? input : path.resolve(input)
  return abs
}
const absWorkingDir = resolveAbsWorkingDir(opts.absWorkingDir)

Type guard

import * as path from 'path'
function isAbsolutePath(p: string): boolean {
  return path.isAbsolute(p)
}

Try / catch

try {
  await esbuild.build({ absWorkingDir, ... })
} catch (e) {
  if (/not an absolute path/i.test(e.message)) {
    console.error('absWorkingDir must be absolute; got:', opts.absWorkingDir)
  }
  throw e
}

Prevention

When it happens

Trigger: Call Build/Context/Transform with options.AbsWorkingDir set to a relative path such as './src' or 'build/out'. Happens via the Go API (pkg/api) and any path that funnels through RealFS. An empty AbsWorkingDir is fine (defaults to os.Getwd()); only a non-empty non-absolute value fails.

Common situations: Hard-coding a relative project root in a config object; reading a cwd from a YAML/.env file that is relative; cross-platform code that builds a Windows path on POSIX or vice versa; passing process.env.PWD which can be relative after symlink resolution.

Related errors


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