apache/seatunnel · error · IllegalArgumentException

python.working.directory is not a directory

Error message

python.working.directory is not a directory: {}

What it means

PythonSourceReader launches a Python child process and optionally sets its working directory from the 'python.working.directory' config option. When that option is set but the path does not exist on disk or resolves to a regular file rather than a directory, the reader refuses to start and throws this IllegalArgumentException during open(). It is a fail-fast config validation so the process is never spawned with a bogus cwd.

Solutions

  1. Fix 'python.working.directory' to point to an existing directory
  2. Create the directory (mkdir -p) before submitting the job
  3. Use an absolute path to avoid surprises from the engine's working directory
  4. Remove the option entirely to default to the script's parent directory

Example fix

// before
python.working.directory = /opt/jobs/python-script.py
// after
python.working.directory = /opt/jobs
Defensive patterns

Strategy: validation

Validate before calling

Path wd = Paths.get(config.getPythonWorkingDirectory());
if (!Files.isDirectory(wd)) {
    throw new IllegalArgumentException("python.working.directory is not a directory: " + wd);
}

Try / catch

try {
    reader.open();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("python.working.directory")) {
        // fix config and revalidate before retry
    }
}

Prevention

When it happens

Trigger: Setting 'python.working.directory' to a path that does not exist, or to a file instead of a directory, then calling open() on the Python source (configureWorkingDirectory).

Common situations: Typo in the path; relative path resolved against a different working directory than the job run directory; path points at a script file instead of its folder; directory deleted after config was written; Docker/K8s container where the mount is missing.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/569d0392dede4bf6. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceReader.java:309

        }
    }

    private Path validateScriptPath() {
        Path scriptPath = Paths.get(sourceConfig.getPythonScriptPath());
        if (!Files.isRegularFile(scriptPath)) {
            throw new IllegalArgumentException(
                    "python.script.path does not point to a readable file: " + scriptPath);
        }
        return scriptPath;
    }

    private void configureWorkingDirectory(ProcessBuilder processBuilder, Path scriptPath) {
        String workingDirectory = sourceConfig.getPythonWorkingDirectory();
        Path processDirectory;
        if (workingDirectory != null && !workingDirectory.trim().isEmpty()) {
            processDirectory = Paths.get(workingDirectory);
            if (!Files.isDirectory(processDirectory)) {
                throw new IllegalArgumentException(
                        "python.working.directory is not a directory: " + processDirectory);
            }
        } else {
            processDirectory = scriptPath.toAbsolutePath().getParent();
        }

        if (processDirectory != null) {
            processBuilder.directory(processDirectory.toFile());
        }
    }

    /**
     * Starts a bounded background write so a script that ignores stdin cannot block open forever.
     */
    private void startStdinWriter(Map<String, Object> scriptConfig) {
        stdinWriterThread =
                new Thread(
                        () -> {

View on GitHub (pinned to cf67b549a7)