apache/seatunnel · error · ClickhouseConnectorException
sourcePath is null
Error message
sourcePath is null
What it means
RsyncFileTransfer.transferAndChown(List<String>, String) rejects a null source path list with ILLEGAL_ARGUMENT / "sourcePath is null" before iterating; each non-null entry is then transferred and ownership-changed via the single-path overload.
Source
Thrown at seatunnel-connectors-v2/connector-clickhouse/src/main/java/org/apache/seatunnel/connectors/seatunnel/clickhouse/sink/file/RsyncFileTransfer.java:168
command.add("ls");
command.add("-l");
command.add(
targetPath.substring(0, StringUtils.stripEnd(targetPath, "/").lastIndexOf("/"))
+ "/");
command.add("| tail -n 1 | awk '{print $3}' | xargs -t -i chown -R {}:{} " + targetPath);
try {
String finalCommand = String.join(" ", command);
log.info("execute remote command: " + finalCommand);
clientSession.executeRemoteCommand(finalCommand);
} catch (IOException e) {
// always return error cause xargs return shell command result
}
}
@Override
public void transferAndChown(List<String> sourcePaths, String targetPath) {
if (sourcePaths == null) {
throw new ClickhouseConnectorException(
CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT, "sourcePath is null");
}
sourcePaths.forEach(sourcePath -> transferAndChown(sourcePath, targetPath));
}
@Override
public void close() {
if (clientSession != null && clientSession.isOpen()) {
try {
clientSession.close();
} catch (IOException e) {
throw new ClickhouseConnectorException(
ClickhouseConnectorErrorCode.SSH_OPERATION_FAILED,
"Failed to close ssh session",
e);
}
}
if (sshClient != null && sshClient.isOpen()) {View on GitHub (pinned to cf67b549a7)
Solutions
- Ensure the caller passes a non-null list; skip the transfer when no files were generated (use an empty list instead of null)
- Initialize the source path list at declaration so it can never be null
- Guard call sites: only invoke transferAndChown when generated file collection succeeded
Example fix
// before
transfer.transferAndChown(clickhouseLocalFiles, targetPath); // may be null
// after
if (clickhouseLocalFiles != null && !clickhouseLocalFiles.isEmpty()) {
transfer.transferAndChown(clickhouseLocalFiles, targetPath);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (sourcePaths == null || sourcePaths.isEmpty()) return; // skip transfer
Type guard
if (sourcePaths == null || sourcePaths.stream().anyMatch(Objects::isNull)) {
throw new IllegalArgumentException("sourcePaths must be a non-null list of non-null paths");
} Prevention
- Initialize file-path lists at declaration, never leave them null
- Skip transfer when no files were generated instead of passing null
- Assert non-null arguments at call sites before invoking transfer APIs
When it happens
Trigger: Calling transferAndChown with a null List<String> of source paths — e.g. an upstream flush step passing null after file generation failed instead of skipping the transfer.
Common situations: Programmatic use of the file transfer API where the caller builds the path list from an operation that returned null; a failed prepareCommit still invoking transfer with an uninitialized list.
Related errors
- splitId must not be null
- sourcePath is null
- ResultSet cannot be null
- RowType cannot be null
- Already an MDCSupplier
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/c2200aa087119c82.
Report an issue: GitHub.