apache/seatunnel · error · AssertConnectorException

RULE_VALIDATION_FAILED

RULE_VALIDATION_FAILED

Error message

row :${element} fail rule: ${failRule}

What it means

Thrown by AssertSinkWriter.write for each row that violates a configured field-level assert rule. AssertExecutor.fail evaluates the row against AssertFieldRule and, if a rule fails (e.g. field not null, min/max, value range), the writer throws RULE_VALIDATION_FAILED embedding the offending row and the failed rule description.

Source

Thrown at seatunnel-connectors-v2/connector-assert/src/main/java/org/apache/seatunnel/connectors/seatunnel/assertion/sink/AssertSinkWriter.java:96

        if (StringUtils.isEmpty(tableName) && StringUtils.isNotEmpty(element.getTableId())) {
            tableName = element.getTableId();
        } else {
            tableName = catalogTableName;
        }

        if (Objects.isNull(assertFieldRule)) {
            assertFieldRule = assertFieldRules.get(tableName);
        }

        LONG_ACCUMULATOR
                .computeIfAbsent(tableName, (k) -> new LongAccumulator(Long::sum, 0))
                .accumulate(1);
        if (Objects.nonNull(assertFieldRule)) {
            ASSERT_EXECUTOR
                    .fail(element, seaTunnelRowType, assertFieldRule)
                    .ifPresent(
                            failRule -> {
                                throw new AssertConnectorException(
                                        AssertConnectorErrorCode.RULE_VALIDATION_FAILED,
                                        "row :" + element + " fail rule: " + failRule);
                            });
        }
    }

    @Override
    public void close() {
        if (!assertRowRules.isEmpty()) {
            assertRowRules.entrySet().stream()
                    .filter(
                            entry ->
                                    !entry.getValue().isEmpty()
                                            && (assertRowRules.size() == 1
                                                    || entry.getKey()
                                                            .equals(this.catalogTableName)))
                    .forEach(
                            entry -> {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Read failRule in the message to identify which field rule the row violated
  2. Fix or filter the offending upstream data
  3. Relax the assert rule (min/max, not-null, allowed values) if it is too strict
  4. Split data quality checks using a transform before asserting if only some rows should be validated

Example fix

// before
rule: field name, assert notNull=true, but row has name=null
// after
Fix source data, or set notNull=false / add a filter transform for null rows
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate rows against the rule before writing
FailRule fail = AssertExecutor.fail(row, rowType, assertFieldRule).orElse(null);
if (fail != null) { sendToDeadLetterQueue(row, fail); return; }

Try / catch

try { writer.write(row); } catch (AssertConnectorException e) { if (RULE_VALIDATION_FAILED.equals(e.getErrorCode())) { log.error("Bad row {}: {}", row, e.getMessage()); /* route to DLQ */ } else throw e; }

Prevention

When it happens

Trigger: write(SeaTunnelRow) called with assertFieldRule != null; AssertExecutor.fail returns a non-empty failRule for the row; thrown immediately during data write, failing the job.

Common situations: Data contains nulls or out-of-range values that the assert rule forbids; rule written for different data (e.g. minRow/maxRow too tight); dirty upstream data in a data-quality gate pipeline.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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