apache/seatunnel · error · FileConnectorException

COMMON_ILLEGAL_ARGUMENT

COMMON_ILLEGAL_ARGUMENT

Error message

file_name_expression must contains <TRANSACTION_EXPRESSION> when is_enable_transaction is true

What it means

FileSinkConfig's constructor validates that when is_enable_transaction is true, the file_name_expression must contain the <TRANSACTION_EXPRESSION> placeholder. Transaction mode needs a unique suffix per attempt so uncommitted/aborted files can be distinguished and cleaned up. Throws FileConnectorException with CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT.

Solutions

  1. Add the placeholder: file_name_expression = "out_<TRANSACTION_EXPRESSION>".
  2. Or set is_enable_transaction = false if exactly-once file commit is not needed.
  3. Use the default file_name_expression, which already contains the transaction expression.

Example fix

// before
file_name_expression = "data_${now}"
is_enable_transaction = true
// after
file_name_expression = "data_${now}_<TRANSACTION_EXPRESSION>"
is_enable_transaction = true
Defensive patterns

Strategy: validation

Validate before calling

if (config.isEnableTransaction && (config.fileNameExpression == null || !config.fileNameExpression.contains("<TRANSACTION_EXPRESSION>"))) {
  throw new IllegalArgumentException("file_name_expression must contain <TRANSACTION_EXPRESSION> when is_enable_transaction=true");
}

Try / catch

try {
  sink.open();
} catch (FileConnectorException e) {
  if (e.getHttpCodeOrCode() == CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT) {
    // fix file_name_expression and resubmit
  }
  throw e;
}

Prevention

When it happens

Trigger: is_enable_transaction = true while file_name_expression is unset or set without '<TRANSACTION_EXPRESSION>' (e.g. 'out_${now}').

Common situations: Users enabling transactional writes for exactly-once semantics but writing a custom filename that drops the placeholder; templates copied from non-transactional examples.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/config/FileSinkConfig.java:137

        if (pluginConfig.getOptional(FileBaseSinkOptions.PARTITION_DIR_EXPRESSION).isPresent()
                && !StringUtils.isBlank(
                        pluginConfig.get(FileBaseSinkOptions.PARTITION_DIR_EXPRESSION))) {
            this.partitionDirExpression =
                    pluginConfig.get(FileBaseSinkOptions.PARTITION_DIR_EXPRESSION);
        }

        this.isPartitionFieldWriteInFile =
                pluginConfig.get(FileBaseSinkOptions.IS_PARTITION_FIELD_WRITE_IN_FILE);

        this.tmpPath = pluginConfig.get(FileBaseSinkOptions.TMP_PATH);

        this.fileNameTimeFormat = pluginConfig.get(FileBaseSinkOptions.FILENAME_TIME_FORMAT);
        this.isEnableTransaction = pluginConfig.get(FileBaseSinkOptions.IS_ENABLE_TRANSACTION);
        this.encoding = pluginConfig.get(FileBaseSinkOptions.ENCODING);

        if (this.isEnableTransaction
                && !this.fileNameExpression.contains(FileBaseSinkOptions.TRANSACTION_EXPRESSION)) {
            throw new FileConnectorException(
                    CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
                    "file_name_expression must contains "
                            + FileBaseSinkOptions.TRANSACTION_EXPRESSION
                            + " when is_enable_transaction is true");
        }

        // check partition field must in seaTunnelRowTypeInfo
        if (!CollectionUtils.isEmpty(this.partitionFieldList)
                && (CollectionUtils.isEmpty(this.sinkColumnList)
                        || !new HashSet<>(this.sinkColumnList)
                                .containsAll(this.partitionFieldList))) {
            throw new FileConnectorException(
                    CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
                    "partition fields must in sink columns");
        }

        if (!CollectionUtils.isEmpty(this.partitionFieldList) && !isPartitionFieldWriteInFile) {
            if (!this.sinkColumnList.removeAll(this.partitionFieldList)) {

View on GitHub (pinned to cf67b549a7)