{"record":{"id":"0b663ac69533c8fc","repo":"apache/seatunnel","slug":"error-handler-max-error-records-must-be-non-negati","errorCode":null,"errorMessage":"error handler max_error_records must be non-negative, but was %s","messagePattern":"error handler max_error_records must be non-negative, but was (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/error/ErrorHandlerConfigUtil.java","lineNumber":80,"sourceCode":"\n        String modeStr = getString(stage, global, \"mode\", \"DISABLE\");\n        ErrorHandlerMode mode = ErrorHandlerMode.fromString(modeStr);\n\n        double maxErrorRatio = getDouble(stage, global, \"max_error_ratio\", 0.0d);\n        if (maxErrorRatio < 0.0d || maxErrorRatio > 1.0d) {\n            throw new IllegalArgumentException(\n                    \"error handler max_error_ratio must be between 0.0 and 1.0, but was \"\n                            + maxErrorRatio);\n        }\n        int maxErrorRatioMinRecords =\n                getNonNegativeInt(\n                        stage,\n                        global,\n                        \"max_error_ratio_min_records\",\n                        DEFAULT_MAX_ERROR_RATIO_MIN_RECORDS);\n        long maxErrorRecords = getLong(stage, global, \"max_error_records\", 0L);\n        if (maxErrorRecords < 0L) {\n            throw new IllegalArgumentException(\n                    \"error handler max_error_records must be non-negative, but was \"\n                            + maxErrorRecords);\n        }\n\n        int queueCapacity = getNonNegativeInt(stage, global, \"queue_capacity\", 10000);\n        String overflowStr = getString(stage, global, \"queue_overflow_policy\", \"FAIL\");\n        QueueOverflowPolicy overflowPolicy = QueueOverflowPolicy.fromString(overflowStr);\n\n        boolean includeStacktrace = getBoolean(stage, global, \"include_stacktrace\", false);\n        boolean includeOriginalData = getBoolean(stage, global, \"include_original_data\", false);\n\n        String dataFormatStr = getString(stage, global, \"original_data_format\", \"TEXT\");\n        if (!\"TEXT\".equalsIgnoreCase(dataFormatStr)) {\n            throw new IllegalArgumentException(\n                    \"Unsupported original_data_format='\"\n                            + dataFormatStr\n                            + \"'. Current version only supports TEXT.\");\n        }","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/error/ErrorHandlerConfigUtil.java#L62-L98","documentation":"IllegalArgumentException from ErrorHandlerConfigUtil.buildStageConfig when max_error_records is negative. The limit is an absolute count of tolerated row-level errors, so only non-negative longs are valid; 0 disables the threshold.","triggerScenarios":"Configuring env.error-handler.max_error_records (global or per stage) with a negative number, e.g. -1 intending 'unlimited'.","commonSituations":"Users using -1 to mean 'no limit' as in other systems; sign typo; templated configs filling in unset variables as -1.","solutions":["Set max_error_records = 0 to disable the record-count threshold (that is the 'unlimited' equivalent).","Use a positive limit matching tolerable dirty-row volume.","Audit global vs stage-level error-handler blocks for stray negative values."],"exampleFix":"// before\nerror-handler { max_error_records = -1 }\n// after\nerror-handler { max_error_records = 0 }","handlingStrategy":"validation","validationCode":"long m = config.getLong(\"max_error_records\");\nif (m < 0) throw new IllegalArgumentException(\"max_error_records must be >= 0 (0 disables the threshold)\");","typeGuard":"boolean isNonNegativeLong(Object v) { return v instanceof Number n && n.longValue() >= 0; }","tryCatchPattern":"try { buildStageConfig(stage, global); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"max_error_records\")) { fixRecordsConfig(); } }","preventionTips":["Use 0, not -1, to disable the record-count threshold","Validate config programmatically before submit","Avoid template variables that fall back to -1 for unset limits"],"tags":["config","validation","threshold"],"backgroundTag":"invalid-config-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}