{"record":{"id":"3f51992ca399f5b5","repo":"apache/seatunnel","slug":"retry-times-must-be-greater-than-0","errorCode":null,"errorMessage":"Retry times must be greater than 0","messagePattern":"Retry times must be greater than 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-common/src/main/java/org/apache/seatunnel/common/utils/RetryUtils.java","lineNumber":41,"sourceCode":"\n@Slf4j\npublic class RetryUtils {\n\n    /**\n     * Execute the given execution with retry\n     *\n     * @param execution execution to execute\n     * @param retryMaterial retry material, defined the condition to retry\n     * @param <T> result type\n     * @return result of execution\n     */\n    public static <T> T retryWithException(\n            Execution<T, Exception> execution, RetryMaterial retryMaterial) throws Exception {\n        final RetryCondition<Exception> retryCondition = retryMaterial.getRetryCondition();\n        final int retryTimes = retryMaterial.getRetryTimes();\n\n        if (retryMaterial.getRetryTimes() < 0) {\n            throw new IllegalArgumentException(\"Retry times must be greater than 0\");\n        }\n        Exception lastException;\n        int i = 0;\n        do {\n            i++;\n            try {\n                return execution.execute();\n            } catch (Exception e) {\n                lastException = e;\n                if (retryCondition != null && !retryCondition.canRetry(e)) {\n                    if (retryMaterial.shouldThrowException()) {\n                        throw e;\n                    }\n                } else {\n                    // Otherwise it is retriable and we should retry\n                    String attemptMessage =\n                            \"Failed to execute due to {}. Retrying attempt ({}/{}) after backoff of {} ms\";\n                    if (retryMaterial.getSleepTimeMillis() > 0) {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-common/src/main/java/org/apache/seatunnel/common/utils/RetryUtils.java#L23-L59","documentation":"RetryUtils.retryWithException validates that the caller-supplied RetryMaterial has non-negative retryTimes before attempting execution. A negative value is rejected with IllegalArgumentException 'Retry times must be greater than 0'. Note the check is < 0, so 0 passes validation (meaning a single attempt, no retries) despite the message wording.","triggerScenarios":"Constructing RetryMaterial (e.g. RetryMaterial.builder().retryTimes(-1)) or otherwise passing a negative retryTimes into retryWithException. Typically caused by misread configuration where a sentinel -1 was intended to mean 'infinite' or 'disabled'.","commonSituations":"Config file value parsed to -1 for retry count; user setting retry-times: -1 expecting unlimited retries; arithmetic producing a negative value from a subtraction on config values.","solutions":["Set retryTimes to a positive integer (>=1) in the RetryMaterial builder or config","If retries should be disabled, use retryTimes 0 rather than a negative value","Validate/clamp the value when loading it from user configuration before constructing RetryMaterial","If unlimited-ish behavior is needed, pass a large retry count with an appropriate retry backoff"],"exampleFix":"// before\nRetryMaterial material = RetryMaterial.builder().retryTimes(-1).build();\n// after\nRetryMaterial material = RetryMaterial.builder().retryTimes(3).build();","handlingStrategy":"validation","validationCode":"int retryTimes = config.getInt(\"retry-times\");\nif (retryTimes < 0) {\n  throw new IllegalArgumentException(\"retry-times must be >= 0, got: \" + retryTimes);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return RetryUtils.retryWithException(execution, material);\n} catch (IllegalArgumentException e) {\n  log.error(\"Invalid retry material: {}\", e.getMessage());\n  throw e;\n}","preventionTips":["Clamp config-derived retry counts to >= 0 at load time","Use 0 (not -1) to mean 'no retries'","Add unit tests for boundary config values","Document valid ranges next to the config option"],"tags":["retry","illegal-argument","config"],"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-14T05:17:10.506Z"}