apache/seatunnel · error · FileConnectorException

ILLEGAL_ARGUMENT

ILLEGAL_ARGUMENT

Error message

Binary sink custom_filename only supports a single source file in each sink task. Existing source file: " + existingRelativePath + ", new source file: " + relativePath

What it means

With custom_filename enabled in a binary sink, each sink task may write at most one source file: the strategy keeps a map from source relativePath to output path, and if a second, different source relativePath arrives while another is already being written it throws ILLEGAL_ARGUMENT. Custom file naming requires a 1:1 mapping between source file and sink task.

Source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/writer/BinaryWriteStrategy.java:111

        String beingWrittenFilePath = beingWrittenFile.get(relativePath);
        if (beingWrittenFilePath != null) {
            return beingWrittenFilePath;
        } else {
            String[] pathSegments = new String[] {transactionDirectory, relativePath};
            String newBeingWrittenFilePath = String.join(File.separator, pathSegments);
            beingWrittenFile.put(relativePath, newBeingWrittenFilePath);
            return newBeingWrittenFilePath;
        }
    }

    private String getOrCreateCustomFilePathBeingWritten(String relativePath) {
        String beingWrittenFilePath = beingWrittenFile.get(relativePath);
        if (beingWrittenFilePath != null) {
            return beingWrittenFilePath;
        } else {
            if (!beingWrittenFile.isEmpty()) {
                String existingRelativePath = beingWrittenFile.keySet().iterator().next();
                throw new FileConnectorException(
                        CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
                        "Binary sink custom_filename only supports a single source file in each "
                                + "sink task. Existing source file: "
                                + existingRelativePath
                                + ", new source file: "
                                + relativePath);
            }
            String[] pathSegments =
                    new String[] {
                        transactionDirectory,
                        FileBaseSinkOptions.NON_PARTITION,
                        generateFileName(transactionId)
                    };
            String newBeingWrittenFilePath = String.join(File.separator, pathSegments);
            beingWrittenFile.put(relativePath, newBeingWrittenFilePath);
            return newBeingWrittenFilePath;
        }
    }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set custom_filename = false to let the sink generate per-output names automatically
  2. Increase sink parallelism so each task handles a single source file, or configure source splits so one file maps to one task
  3. Remove the merge/small-file compaction option on the source so tasks are not assigned multiple files

Example fix

// before
sink {
  LocalFile {
    file_format_type = "binary"
    custom_filename = true
  }
}
// after
sink {
  LocalFile {
    file_format_type = "binary"
    custom_filename = false
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// before enabling custom_filename on a binary sink
if (sinkConfig.customFilename && expectedSourceFilesPerTask > 1) {
  throw new IllegalArgumentException("custom_filename=true requires exactly one source file per sink task");
}

Try / catch

try { strategy.getOrCreateCustomFilePathBeingWritten(relativePath); } catch (FileConnectorException e) {
  if (CommonErrorCode.ILLEGAL_ARGUMENT.equals(e.getErrorCode())) {
    /* disable custom_filename or re-shard source files one-per-task */
  }
}

Prevention

When it happens

Trigger: getOrCreateCustomFilePathBeingWritten (called via getOrCreateFilePathBeingWritten) receives a new relativePath while beingWrittenFile already holds a different, non-empty entry — e.g. one sink task assigned multiple source files.

Common situations: custom_filename = true with source parallelism/splits causing multiple source files to land in the same sink task; small source files merged so one reader task covers several files.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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