{"id":"b3628cc815b6f7ff","repo":"evanw/esbuild","slug":"the-working-directory-q-is-not-an-absolute-path","errorCode":null,"errorMessage":"The working directory %q is not an absolute path","messagePattern":"The working directory %q is not an absolute path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/fs/fs_real.go","lineNumber":86,"sourceCode":"\t\tfp.isWindows = true\n\t\tfp.pathSeparator = '\\\\'\n\t} else {\n\t\tfp.isWindows = false\n\t\tfp.pathSeparator = '/'\n\t}\n\n\t// Come up with a default working directory if one was not specified\n\tfp.cwd = options.AbsWorkingDir\n\tif fp.cwd == \"\" {\n\t\tif cwd, err := os.Getwd(); err == nil {\n\t\t\tfp.cwd = cwd\n\t\t} else if fp.isWindows {\n\t\t\tfp.cwd = \"C:\\\\\"\n\t\t} else {\n\t\t\tfp.cwd = \"/\"\n\t\t}\n\t} else if !fp.isAbs(fp.cwd) {\n\t\treturn nil, fmt.Errorf(\"The working directory %q is not an absolute path\", fp.cwd)\n\t}\n\n\t// Resolve symlinks in the current working directory. Symlinks are resolved\n\t// when input file paths are converted to absolute paths because we need to\n\t// recognize an input file as unique even if it has multiple symlinks\n\t// pointing to it. The build will generate relative paths from the current\n\t// working directory to the absolute input file paths for error messages,\n\t// so the current working directory should be processed the same way. Not\n\t// doing this causes test failures with esbuild when run from inside a\n\t// symlinked directory.\n\t//\n\t// This deliberately ignores errors due to e.g. infinite loops. If there is\n\t// an error, we will just use the original working directory and likely\n\t// encounter an error later anyway. And if we don't encounter an error\n\t// later, then the current working directory didn't even matter and the\n\t// error is unimportant.\n\tif path, err := fp.evalSymlinks(fp.cwd); err == nil {\n\t\tfp.cwd = path","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/internal/fs/fs_real.go#L68-L104","documentation":"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 '/').","triggerScenarios":"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.","commonSituations":"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.","solutions":["Resolve the path to absolute before passing it: use path.resolve (JS) or filepath.Abs (Go).","Omit AbsWorkingDir entirely to let esbuild use the current working directory.","On Windows, ensure the path includes a drive letter and backslashes, e.g. C:\\\\project\\\\src.","Log the value of AbsWorkingDir right before the build call to catch stray relative inputs."],"exampleFix":"// before\nimport * as esbuild from 'esbuild'\nesbuild.build({ absWorkingDir: './src', ... })\n\n// after\nimport * as path from 'path'\nesbuild.build({ absWorkingDir: path.resolve('./src'), ... })","handlingStrategy":"validation","validationCode":"import * as path from 'path'\nfunction resolveAbsWorkingDir(input) {\n  if (!input) return process.cwd()\n  const abs = path.isAbsolute(input) ? input : path.resolve(input)\n  return abs\n}\nconst absWorkingDir = resolveAbsWorkingDir(opts.absWorkingDir)","typeGuard":"import * as path from 'path'\nfunction isAbsolutePath(p: string): boolean {\n  return path.isAbsolute(p)\n}","tryCatchPattern":"try {\n  await esbuild.build({ absWorkingDir, ... })\n} catch (e) {\n  if (/not an absolute path/i.test(e.message)) {\n    console.error('absWorkingDir must be absolute; got:', opts.absWorkingDir)\n  }\n  throw e\n}","preventionTips":["Always pass absWorkingDir through path.resolve before assigning it.","Treat an empty absWorkingDir as 'use cwd' rather than letting a relative string through.","Cross-platform: build paths with path.join, never string concatenation of separators."],"tags":["filesystem","working-dir","absolute-path","config","cross-platform"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}