{"record":{"id":"42324cf4e227631a","repo":"junit-team/junit5","slug":"timeout-duration-is-not-in-the-expected-format-n","errorCode":null,"errorMessage":"Timeout duration is not in the expected format (<number> [ns|μs|ms|s|m|h|d])","messagePattern":"Timeout duration is not in the expected format \\(<number> \\[ns\\|μs\\|ms\\|s\\|m\\|h\\|d\\]\\)","errorType":"exception","errorClass":"DateTimeParseException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutDurationParser.java","lineNumber":58,"sourceCode":"\t\t\"ns\", NANOSECONDS, //\n\t\t\"μs\", MICROSECONDS, //\n\t\t\"ms\", MILLISECONDS, //\n\t\t\"s\", SECONDS, //\n\t\t\"m\", MINUTES, //\n\t\t\"h\", HOURS, //\n\t\t\"d\", DAYS //\n\t);\n\n\tTimeoutDuration parse(CharSequence text) throws DateTimeParseException {\n\t\tMatcher matcher = PATTERN.matcher(text);\n\t\tif (matcher.matches()) {\n\t\t\tlong value = Long.parseLong(matcher.group(1));\n\t\t\tString unitAbbreviation = matcher.group(2);\n\t\t\tTimeUnit unit = unitAbbreviation == null ? SECONDS\n\t\t\t\t\t: requireNonNull(UNITS_BY_ABBREVIATION.get(unitAbbreviation.toLowerCase(Locale.ENGLISH)));\n\t\t\treturn new TimeoutDuration(value, unit);\n\t\t}\n\t\tthrow new DateTimeParseException(\"Timeout duration is not in the expected format (<number> [ns|μs|ms|s|m|h|d])\",\n\t\t\ttext, 0);\n\t}\n\n}\n","sourceCodeStart":40,"sourceCodeEnd":63,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutDurationParser.java#L40-L63","documentation":"Thrown when a timeout duration string supplied to @Timeout (or the junit.jupiter.execution.timeout.* configuration parameters) does not match the expected pattern: a positive integer (starting with 1-9) optionally followed by a unit abbreviation (ns, μs, ms, s, m, h, d). The parser uses a strict regex ([1-9]\\d*) so values like '0', '1.5s', '500ms ' with trailing junk, or '-3' all fail. If no unit is given, seconds is assumed.","triggerScenarios":"Set junit.jupiter.execution.timeout.testmethod.default to a malformed string like '0', '-1', '1.5', 'abc', or '100x'. Annotate a test with @Timeout(value=0) or pass a duration string containing an unrecognized unit. Using 'us' instead of the Unicode 'μs' microsecond abbreviation also fails because the regex only matches [nμm]?s.","commonSituations":"Developers commonly hit this when migrating from another timeout library that uses 'us' for microseconds, or when supplying fractional values like '1.5s'. Another frequent case is setting the timeout to '0' expecting 'no timeout', which the regex rejects because it requires [1-9] as the first digit. Copy-pasting timeout values from documentation that uses a different unit abbreviation scheme (e.g., 'sec' or 'min') also triggers it.","solutions":["Ensure the duration string is a positive integer (no leading zeros, no decimals) optionally followed by one of: ns, μs, ms, s, m, h, d","If you need microseconds, use the Unicode micro symbol μ (U+00B5), not the ASCII 'u'","If you intended 'no timeout', remove the @Timeout annotation or configuration parameter rather than setting it to 0","For fractional timeouts, round up to the nearest integer and use a smaller unit (e.g., '1500ms' instead of '1.5s')"],"exampleFix":"// before\n@Timeout(value = 0, unit = TimeUnit.SECONDS)\nvoid myTest() { }\n\n// Or in configuration:\n// junit.jupiter.execution.timeout.testmethod.default = 1.5s\n\n// after\n@Timeout(value = 5, unit = TimeUnit.SECONDS)\nvoid myTest() { }\n\n// Or via configuration parameter (integer + optional unit):\n// junit.jupiter.execution.timeout.testmethod.default = 500ms","handlingStrategy":"validation","validationCode":"// Validate timeout string before passing to configuration\nimport java.util.regex.Pattern;\n\nprivate static final Pattern TIMEOUT_PATTERN =\n    Pattern.compile(\"([1-9]\\\\d*) ?((?:[nμm]?s)|m|h|d)?\", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);\n\nstatic boolean isValidTimeout(String value) {\n    return value != null && TIMEOUT_PATTERN.matcher(value).matches();\n}\n\n// Usage before setting configuration:\nString timeout = \"500ms\";\nif (!isValidTimeout(timeout)) {\n    throw new IllegalArgumentException(\"Invalid timeout format: \" + timeout);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always test timeout configuration values in a throwaway test before committing them","Document the valid unit abbreviations in your project's testing guide, emphasizing μ (not u) for microseconds","Use TimeUnit enum-based @Timeout(value=N, unit=TimeUnit.X) API instead of string-based configuration where possible"],"tags":["timeout","configuration","junit-jupiter","parsing"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}