{"record":{"id":"f1bbd6fcf2ed99fd","repo":"apache/seatunnel","slug":"sourcepath-is-null-f1bbd6","errorCode":null,"errorMessage":"sourcePath is null","messagePattern":"sourcePath is null","errorType":"validation","errorClass":"ClickhouseConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/sink/file/ScpFileTransfer.java","lineNumber":129,"sourceCode":"        command.add(\"ls\");\n        command.add(\"-l\");\n        command.add(\n                targetPath.substring(0, StringUtils.stripEnd(targetPath, \"/\").lastIndexOf(\"/\"))\n                        + \"/\");\n        command.add(\"| tail -n 1 | awk '{print $3}' | xargs -t -i chown -R {}:{} \" + targetPath);\n        try {\n            String finalCommand = String.join(\" \", command);\n            log.info(\"execute remote command: \" + finalCommand);\n            clientSession.executeRemoteCommand(finalCommand);\n        } catch (IOException e) {\n            // always return error cause xargs return shell command result\n        }\n    }\n\n    @Override\n    public void transferAndChown(List<String> sourcePaths, String targetPath) {\n        if (sourcePaths == null) {\n            throw new ClickhouseConnectorException(\n                    CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT, \"sourcePath is null\");\n        }\n        sourcePaths.forEach(sourcePath -> transferAndChown(sourcePath, targetPath));\n    }\n\n    @Override\n    public void close() {\n        if (clientSession != null && clientSession.isOpen()) {\n            try {\n                clientSession.close();\n            } catch (IOException e) {\n                throw new ClickhouseConnectorException(\n                        ClickhouseConnectorErrorCode.SSH_OPERATION_FAILED,\n                        \"Failed to close ssh session\",\n                        e);\n            }\n        }\n        if (sshClient != null && sshClient.isOpen()) {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/sink/file/ScpFileTransfer.java#L111-L147","documentation":"ScpFileTransfer.transferAndChown(List<String> sourcePaths, String targetPath) validates its input and throws ILLEGAL_ARGUMENT when the sourcePaths list is null. This is a fail-fast argument check before delegating each path to the single-path transfer.","triggerScenarios":"Calling transferAndChown with a null List argument — e.g. upstream code that built the file list conditionally and never assigned it, or a config that produced no files and the list was left null instead of empty.","commonSituations":"Programmatic use of the ClickHouse sink's file transfer API where the local temp-file collection step failed silently and returned null instead of an empty list.","solutions":["Ensure the caller initializes the source file list before invoking transferAndChown","Pass an empty list instead of null if there are legitimately no files to transfer","Trace where the list is produced and fix the code path that leaves it null"],"exampleFix":"// before\nList<String> sourcePaths = null;\ntransfer.transferAndChown(sourcePaths, targetPath);\n// after\nList<String> sourcePaths = collectedFiles != null ? collectedFiles : Collections.emptyList();\ntransfer.transferAndChown(sourcePaths, targetPath);","handlingStrategy":"type-guard","validationCode":"if (sourcePaths == null) {\n    throw new IllegalArgumentException(\"sourcePaths must not be null; pass an empty list instead\");\n}","typeGuard":"boolean hasValidSourcePaths = (sourcePaths != null);","tryCatchPattern":"try {\n    transfer.transferAndChown(sourcePaths, targetPath);\n} catch (ClickhouseConnectorException e) {\n    if (\"sourcePath is null\".equals(e.getMessage())) {\n        log.error(\"File list was null; check upstream collection step\");\n    }\n    throw e;\n}","preventionTips":["Initialize file-list variables to empty lists, never null","Fail fast upstream when local file collection produces null","Prefer Collections.emptyList() as default value"],"tags":["argument-validation","null","scp","clickhouse"],"backgroundTag":"null-argument","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"}