{"record":{"id":"43cc8abd00dc6c71","repo":"apache/seatunnel","slug":"option-key-must-be-greater-than-or-equal-to","errorCode":null,"errorMessage":"'${option.key()}' must be greater than or equal to 0.","messagePattern":"'(.+?)' must be greater than or equal to 0\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mysql/source/MySqlIncrementalSource.java","lineNumber":184,"sourceCode":"        }\n\n        try {\n            new GtidSet(gtidSet);\n        } catch (Exception e) {\n            throw new IllegalArgumentException(\n                    String.format(\n                            \"Invalid '%s' value '%s'.\",\n                            MySqlIncrementalSourceOptions.STARTUP_SPECIFIC_OFFSET_GTID_SET.key(),\n                            gtidSet),\n                    e);\n        }\n        return Optional.of(gtidSet);\n    }\n\n    private static long getNonNegativeSkipValue(ReadonlyConfig config, Option<Long> option) {\n        long value = config.getOptional(option).orElse(0L);\n        if (value < 0) {\n            throw new IllegalArgumentException(\n                    String.format(\"'%s' must be greater than or equal to 0.\", option.key()));\n        }\n        return value;\n    }\n\n    private static void validateNoSpecificStartupOffset(\n            ReadonlyConfig config, StartupMode startupMode) {\n        if (hasSpecificStartupOffset(config)) {\n            throw new IllegalArgumentException(\n                    String.format(\n                            \"'startup.specific-offset.*' options can only be used when '%s' is 'specific', but current mode is '%s'.\",\n                            SourceOptions.STARTUP_MODE_KEY, startupMode));\n        }\n    }\n\n    private static boolean hasSpecificStartupOffset(ReadonlyConfig config) {\n        return config.getOptional(SourceOptions.STARTUP_SPECIFIC_OFFSET_FILE).isPresent()\n                || config.getOptional(SourceOptions.STARTUP_SPECIFIC_OFFSET_POS).isPresent()","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mysql/source/MySqlIncrementalSource.java#L166-L202","documentation":"getNonNegativeSkipValue validates startup.specific-offset.skip-cdcs and startup.specific-offset.skip-events (skip rows/events) which must be >= 0. A negative configured value throws IllegalArgumentException naming the offending option key.","triggerScenarios":"createSpecificStartupOffset calling getNonNegativeSkipValue for skip.rows/skip.events with a configured value < 0 (default 0 when absent).","commonSituations":"User tries to 'rewind' events with a negative skip; sign typo (-1 as placeholder); templated config where a negative default leaked in.","solutions":["Set the skip option to 0 or a positive number","Remove the negative key to use the default of 0","If the goal is to start earlier, choose an earlier binlog file/position or GTID set instead of negative skip"],"exampleFix":"// before\nspecific-offset.skip-events = -100\n// after\nspecific-offset.skip-events = 0","handlingStrategy":"validation","validationCode":"long skip = config.getOptional(\"startup.specific-offset.skip-events\").orElse(0L);\nif (skip < 0) throw new IllegalArgumentException(\"skip-events must be >= 0\");","typeGuard":null,"tryCatchPattern":"try { createSource(config); } catch (IllegalArgumentException e) { LOG.error(\"Negative skip value: {}\", e.getMessage()); throw new ConfigException(e); }","preventionTips":["Never use negative numbers as placeholders in skip options","Clamp/template defaults to 0","Note that rewinding is done via earlier offsets, not negative skip"],"tags":["cdc","mysql","config-validation"],"backgroundTag":"value-out-of-range","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"}