jenkinsci/jenkins · error · IOException

Process working directory '%s' doesn't exist!

Error message

Process working directory '%s' doesn't exist!

What it means

Thrown in the LocalProc constructor when the ProcessBuilder's configured working directory exists as a path object but does not actually exist on the filesystem. The message includes the absolute path of the missing directory. This is a pre-launch guard before procBuilder.start() is called.

Source

Thrown at core/src/main/java/hudson/Proc.java:247

            if (env != null) {
                Map<String, String> m = pb.environment();
                m.clear();
                for (String e : env) {
                    int idx = e.indexOf('=');
                    m.put(e.substring(0, idx), e.substring(idx + 1));
                }
            }
            return pb;
        }

        private LocalProc(String name, ProcessBuilder procBuilder, InputStream in, OutputStream out, OutputStream err) throws IOException {
            Logger.getLogger(Proc.class.getName()).log(Level.FINE, "Running: {0}", name);
            this.name = name;
            this.out = out;
            this.cookie = EnvVars.createCookie();
            procBuilder.environment().putAll(cookie);
            if (procBuilder.directory() != null && !procBuilder.directory().exists()) {
                throw new IOException(String.format("Process working directory '%s' doesn't exist!", procBuilder.directory().getAbsolutePath()));
            }
            this.proc = procBuilder.start();

            InputStream procInputStream = proc.getInputStream();
            if (out == SELFPUMP_OUTPUT) {
                stdout = procInputStream;
                copier = null;
            } else {
                copier = new StreamCopyThread(name + ": stdout copier", procInputStream, out);
                copier.start();
                stdout = null;
            }

            if (in == null) {
                // nothing to feed to stdin
                stdin = null;
                proc.getOutputStream().close();
            } else

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Verify the agent's 'Remote root directory' setting in Manage Jenkins → Nodes points to an existing, writable directory.
  2. Ensure any custom workspace path passed to the launcher is created before launching the process (e.g., via a pre-build shell step that runs mkdir -p).
  3. Check for external cleanup (cron jobs, disk cleanup plugins) that may have deleted the directory.
  4. If running inside a container, verify the volume mount for the workspace is correctly configured and the mount point exists.

Example fix

// before
Launcher launcher = node.createLauncher(taskListener);
launcher.launch().cmds(cmds).pwd(workspacePath).start();

// after
if (!Files.exists(workspacePath)) {
    Files.createDirectories(workspacePath);
}
Launcher launcher = node.createLauncher(taskListener);
launcher.launch().cmds(cmds).pwd(workspacePath).start();
Defensive patterns

Strategy: validation

Validate before calling

// Validate working directory before launching
Path workDir = node.getRootPath().toPath(); // or custom workspace
if (!Files.exists(workDir)) {
    Files.createDirectories(workDir);
}
Launcher launcher = node.createLauncher(listener);

Try / catch

try {
    proc = launcher.launch().cmds(cmds).pwd(workDir).start();
} catch (IOException e) {
    if (e.getMessage().contains("doesn't exist")) {
        // Recreate directory and retry once
        Files.createDirectories(workDir);
        proc = launcher.launch().cmds(cmds).pwd(workDir).start();
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: A Launcher.LocalLauncher (or direct LocalProc instantiation) creates a ProcessBuilder with directory() set to a path, then checks procBuilder.directory().exists() — if false, it throws. The check runs after cookie/cookie env injection but before procBuilder.start().

Common situations: An agent's remote FS root (configured in node settings) points to a deleted or unmounted directory; a build step references a custom workspace path that was cleaned up by a previous build or never created; running on a Docker container where the mount point for the workspace is not present; a tool installer's home directory was removed.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/1891006dfd97aa4f. Report an issue: GitHub.