{"record":{"id":"de7dca4f1cd75a26","repo":"testcontainers/testcontainers-java","slug":"flaky-annotation-maxtries-must-be-at-least-one","errorCode":null,"errorMessage":"@Flaky annotation maxTries must be at least one","messagePattern":"@Flaky annotation maxTries must be at least one","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"test-support/src/main/java/org/testcontainers/testsupport/FlakyTestJUnit4RetryRule.java","lineNumber":48,"sourceCode":"public class FlakyTestJUnit4RetryRule implements TestRule {\n\n    @Override\n    public Statement apply(Statement base, Description description) {\n        final Flaky annotation = description.getAnnotation(Flaky.class);\n\n        if (annotation == null) {\n            // leave the statement as-is\n            return base;\n        }\n\n        if (annotation.githubIssueUrl().trim().length() == 0) {\n            throw new IllegalArgumentException(\"A GitHub issue URL must be set for usages of the @Flaky annotation\");\n        }\n\n        final int maxTries = annotation.maxTries();\n\n        if (maxTries < 1) {\n            throw new IllegalArgumentException(\"@Flaky annotation maxTries must be at least one\");\n        }\n\n        final LocalDate reviewDate;\n        try {\n            reviewDate = LocalDate.parse(annotation.reviewDate());\n        } catch (DateTimeParseException e) {\n            throw new IllegalArgumentException(\n                \"@Flaky reviewDate could not be parsed. Please provide a date in yyyy-mm-dd format\"\n            );\n        }\n\n        // the annotation should only have an effect before the review date, to encourage review and resolution\n        if (LocalDate.now().isBefore(reviewDate)) {\n            return new RetryingStatement(base, description, maxTries);\n        } else {\n            return base;\n        }\n    }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/test-support/src/main/java/org/testcontainers/testsupport/FlakyTestJUnit4RetryRule.java#L30-L66","documentation":"FlakyTestJUnit4RetryRule enforces that maxTries is at least 1; a value below 1 would make the retry rule meaningless (the test would never run). It throws IllegalArgumentException at rule application time.","triggerScenarios":"Declaring @Flaky(maxTries = 0) or a negative maxTries on a test method.","commonSituations":"Copy-paste of the annotation with placeholder values; attempts to 'disable' a flaky test by setting maxTries to 0 instead of removing the annotation.","solutions":["Set maxTries to a value >= 1 (typically 2-5)","Remove @Flaky entirely to disable retries","Use JUnit's @Ignore if the intent was to skip the test"],"exampleFix":"// before\n@Flaky(githubIssueUrl = \"...\", maxTries = 0)\n// after\n@Flaky(githubIssueUrl = \"...\", maxTries = 3)","handlingStrategy":"validation","validationCode":"Flaky flaky = m.getAnnotation(Flaky.class);\nif (flaky != null && flaky.maxTries() < 1) throw new IllegalStateException(\"maxTries must be >= 1\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat maxTries=0 as invalid — remove @Flaky to disable retries","Default to 2-3 tries for genuinely intermittent tests","Lint annotations in CI"],"tags":["test-support","junit","annotation-validation"],"backgroundTag":"value-out-of-range","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}