{"record":{"id":"a3a0f60feac07e9e","repo":"apache/seatunnel","slug":"python-executable-must-not-be-blank","errorCode":null,"errorMessage":"python.executable must not be blank","messagePattern":"python\\.executable must not be blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceConfig.java","lineNumber":86,"sourceCode":"    public String getPythonWorkingDirectory() {\n        return pythonWorkingDirectory;\n    }\n\n    public String getFileFormatType() {\n        return fileFormatType;\n    }\n\n    public String getFieldDelimiter() {\n        return fieldDelimiter;\n    }\n\n    /**\n     * Phase 1 keeps the stdout contract intentionally narrow so the first implementation can stay\n     * compatible with the existing text deserializer.\n     */\n    private void validate() {\n        if (StringUtils.isBlank(pythonExecutable)) {\n            throw new IllegalArgumentException(\"python.executable must not be blank\");\n        }\n        if (StringUtils.isBlank(pythonScriptPath)) {\n            throw new IllegalArgumentException(\"python.script.path must not be blank\");\n        }\n        if (!SUPPORTED_FILE_FORMAT.equalsIgnoreCase(fileFormatType)) {\n            throw new IllegalArgumentException(\n                    \"Unsupported file_format_type: \"\n                            + fileFormatType\n                            + \". Phase 1 supports only text\");\n        }\n        if (fieldDelimiter == null) {\n            throw new IllegalArgumentException(\"field_delimiter must not be null\");\n        }\n    }\n}\n","sourceCodeStart":68,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceConfig.java#L68-L102","documentation":"PythonSourceConfig.validate() throws this IllegalArgumentException when the configured python.executable option is null, empty, or whitespace-only. The Python source requires an interpreter path to spawn its subprocess, so a blank value makes the config invalid before any execution.","triggerScenarios":"Building PythonSourceConfig from a job config where the python.executable option is omitted or set to \"\"/whitespace; validate() runs during config construction and fails immediately.","commonSituations":"Copy-pasting a config template without filling in python.executable; relying on an old config key that no longer applies; assuming the server's default python is used instead of an explicit path.","solutions":["Set python.executable in the source config to an absolute interpreter path, e.g. \"/usr/bin/python3\".","Ensure the value has no surrounding whitespace-only content or stray quotes.","Verify the interpreter exists on every worker node where the source will run.","Combine with -Dpython.allowed.executables so the configured path is permitted by the execution policy."],"exampleFix":"// before\nPython {\n  python.executable = \"\"\n}\n// after\nPython {\n  python.executable = \"/usr/bin/python3\"\n}","handlingStrategy":"validation","validationCode":"// Java: validate the map before constructing PythonSourceConfig\nString exe = configMap.get(\"python.executable\");\nif (exe == null || exe.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"python.executable is required and must not be blank\");\n}","typeGuard":null,"tryCatchPattern":"try { cfg = new PythonSourceConfig(configMap); } catch (IllegalArgumentException e) { LOG.error(\"Invalid python source config: {}\", e.getMessage()); }","preventionTips":["Always set an absolute interpreter path in the config","Strip whitespace from interpolated config values","Lint job configs for required Python source options before submit"],"tags":["python","config-validation","required-option"],"backgroundTag":"missing-required-config-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}