pulumi/pulumi · error · Error

Invalid workDir passed to local workspace: '${workDir}' does

Error message

Invalid workDir passed to local workspace: '${workDir}' does not exist

What it means

During LocalWorkspace setup (sdk/nodejs/automation/localWorkspace.ts:367), if `opts.workDir` is supplied the constructor verifies it exists with `fs.existsSync`; if not it throws `Invalid workDir passed to local workspace: '<workDir>' does not exist`. The Automation API refuses to build a workspace rooted at a missing directory.

Source

Thrown at sdk/nodejs/automation/localWorkspace.ts:367

        if (opts) {
            const {
                workDir,
                pulumiHome,
                program,
                remoteExecutorImage,
                envVars,
                secretsProvider,
                remote,
                remoteGitProgramArgs,
                remotePreRunCommands,
                remoteEnvVars,
                remoteSkipInstallDependencies,
                remoteInheritSettings,
            } = opts;
            if (workDir) {
                // Verify that the workdir exists.
                if (!fs.existsSync(workDir)) {
                    throw new Error(`Invalid workDir passed to local workspace: '${workDir}' does not exist`);
                }
                dir = workDir;
            }
            this.pulumiHome = pulumiHome;
            this.remoteExecutorImage = remoteExecutorImage;
            this.program = program;
            this.secretsProvider = secretsProvider;
            this.remote = remote;
            this.remoteGitProgramArgs = remoteGitProgramArgs;
            this.remotePreRunCommands = remotePreRunCommands;
            this.remoteEnvVars = { ...remoteEnvVars };
            this.remoteSkipInstallDependencies = remoteSkipInstallDependencies;
            this.remoteInheritSettings = remoteInheritSettings;
            envs = { ...envVars };
        }

        if (!dir) {
            dir = fs.mkdtempSync(upath.joinSafe(os.tmpdir(), "automation-"));

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Create the directory before constructing the workspace: `fs.mkdirSync(workDir, { recursive: true })`.
  2. Use absolute paths (`path.resolve(...)`) to avoid CWD ambiguity.
  3. Verify the path exists: `fs.existsSync(workDir)` or `ls <workDir>` before running.
  4. Fix typos in the configured path; check CI checkout/mount configuration.
  5. If omitting `workDir`, the workspace defaults to the current directory — make sure CWD is correct.

Example fix

// before
await LocalWorkspace.create({ stackName: "dev", workDir: "./nonexistent/app" });
// after
const workDir = path.resolve("./app");
fs.mkdirSync(workDir, { recursive: true });
await LocalWorkspace.create({ stackName: "dev", workDir });
Defensive patterns

Strategy: validation

Validate before calling

import fs from "fs";
import path from "path";
const workDir = path.resolve(process.env.PROJECT_DIR ?? "./app");
if (!fs.existsSync(workDir)) fs.mkdirSync(workDir, { recursive: true });
// then pass workDir to LocalWorkspaceOptions

Type guard

function isValidWorkDir(p: string): boolean {
  return fs.existsSync(p) && fs.statSync(p).isDirectory();
}

Try / catch

try {
  const ws = await LocalWorkspace.create({ workDir });
} catch (err) {
  if (String(err).includes("Invalid workDir passed to local workspace")) {
    fs.mkdirSync(workDir, { recursive: true });
    // retry creation
  } else throw err;
}

Prevention

When it happens

Trigger: Passing `workDir` in `LocalWorkspaceOptions` (to LocalWorkspace.create, Stack.create, createOrSelectStack, etc.) pointing to a directory that does not exist at construction time — wrong relative path, typo, or directory deleted/not yet created in CI.

Common situations: Relative paths resolved against a different CWD in CI vs local; project checked out into a different path in CI; directory created later by a build step that hasn't run yet; typos like `./src` vs `./source`; running from a container where the path was never mounted.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/08b5f210fa93bbfe. Report an issue: GitHub.