{"record":{"id":"9c519a339f7872a0","repo":"apache/seatunnel","slug":"rule-validation-failed","errorCode":"RULE_VALIDATION_FAILED","errorMessage":"row :${element} fail rule: ${failRule}","messagePattern":"row :(.+?) fail rule: (.+?)","errorType":"error_code","errorClass":"AssertConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-assert/src/main/java/org/apache/seatunnel/connectors/seatunnel/assertion/sink/AssertSinkWriter.java","lineNumber":96,"sourceCode":"        if (StringUtils.isEmpty(tableName) && StringUtils.isNotEmpty(element.getTableId())) {\n            tableName = element.getTableId();\n        } else {\n            tableName = catalogTableName;\n        }\n\n        if (Objects.isNull(assertFieldRule)) {\n            assertFieldRule = assertFieldRules.get(tableName);\n        }\n\n        LONG_ACCUMULATOR\n                .computeIfAbsent(tableName, (k) -> new LongAccumulator(Long::sum, 0))\n                .accumulate(1);\n        if (Objects.nonNull(assertFieldRule)) {\n            ASSERT_EXECUTOR\n                    .fail(element, seaTunnelRowType, assertFieldRule)\n                    .ifPresent(\n                            failRule -> {\n                                throw new AssertConnectorException(\n                                        AssertConnectorErrorCode.RULE_VALIDATION_FAILED,\n                                        \"row :\" + element + \" fail rule: \" + failRule);\n                            });\n        }\n    }\n\n    @Override\n    public void close() {\n        if (!assertRowRules.isEmpty()) {\n            assertRowRules.entrySet().stream()\n                    .filter(\n                            entry ->\n                                    !entry.getValue().isEmpty()\n                                            && (assertRowRules.size() == 1\n                                                    || entry.getKey()\n                                                            .equals(this.catalogTableName)))\n                    .forEach(\n                            entry -> {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-assert/src/main/java/org/apache/seatunnel/connectors/seatunnel/assertion/sink/AssertSinkWriter.java#L78-L114","documentation":"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.","triggerScenarios":"write(SeaTunnelRow) called with assertFieldRule != null; AssertExecutor.fail returns a non-empty failRule for the row; thrown immediately during data write, failing the job.","commonSituations":"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.","solutions":["Read failRule in the message to identify which field rule the row violated","Fix or filter the offending upstream data","Relax the assert rule (min/max, not-null, allowed values) if it is too strict","Split data quality checks using a transform before asserting if only some rows should be validated"],"exampleFix":"// before\nrule: field name, assert notNull=true, but row has name=null\n// after\nFix source data, or set notNull=false / add a filter transform for null rows","handlingStrategy":"try-catch","validationCode":"// pre-validate rows against the rule before writing\nFailRule fail = AssertExecutor.fail(row, rowType, assertFieldRule).orElse(null);\nif (fail != null) { sendToDeadLetterQueue(row, fail); return; }","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Profile upstream data (null rates, ranges) before setting assert thresholds","Use max-allow/fail-on-row settings that tolerate realistic dirty-data rates","Stage data through a filter/transform to quarantine bad rows before the assert sink","Keep assert rules aligned with the contract documented for the source"],"tags":["assert-connector","data-quality","row-validation"],"backgroundTag":"schema-validation-failed","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"}