{"record":{"id":"94199683ecca3e04","repo":"apache/incubator-seata","slug":"str-can-t-parse-to-duration","errorCode":null,"errorMessage":"\"\\\"\" + str + \"\\\" can't parse to Duration\"","messagePattern":"\"\\\\\"\" \\+ str \\+ \"\\\\\" can't parse to Duration\"","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/org/apache/seata/common/util/DurationUtil.java","lineNumber":58,"sourceCode":"\n        if (SIMPLE.matcher(str).matches()) {\n            if (str.contains(MILLIS_SECOND_UNIT)) {\n                long value = doParse(MILLIS_SECOND_UNIT, str);\n                return Duration.ofMillis(value);\n            } else if (str.contains(DAY_UNIT)) {\n                long value = doParse(DAY_UNIT, str);\n                return Duration.ofDays(value);\n            } else if (str.contains(HOUR_UNIT)) {\n                long value = doParse(HOUR_UNIT, str);\n                return Duration.ofHours(value);\n            } else if (str.contains(MINUTE_UNIT)) {\n                long value = doParse(MINUTE_UNIT, str);\n                return Duration.ofMinutes(value);\n            } else if (str.contains(SECOND_UNIT)) {\n                long value = doParse(SECOND_UNIT, str);\n                return Duration.ofSeconds(value);\n            } else {\n                throw new UnsupportedOperationException(\"\\\"\" + str + \"\\\" can't parse to Duration\");\n            }\n        }\n\n        try {\n            if (ISO8601.matcher(str).matches()) {\n                return Duration.parse(str);\n            }\n        } catch (DateTimeParseException e) {\n            throw new UnsupportedOperationException(\"\\\"\" + str + \"\\\" can't parse to Duration\", e);\n        }\n\n        try {\n            int millis = Integer.parseInt(str);\n            return Duration.ofMillis(millis);\n        } catch (Exception e) {\n            throw new UnsupportedOperationException(\"\\\"\" + str + \"\\\" can't parse to Duration\", e);\n        }\n    }","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/common/src/main/java/org/apache/seata/common/util/DurationUtil.java#L40-L76","documentation":"DurationUtil.parse accepts a simple format <number><unit> where unit is ms, d, h, m, or s, an ISO-8601 duration (P...), or a bare integer interpreted as milliseconds. This branch fires when the SIMPLE regex matched (digits plus 1-2 letters) but the unit letter is none of the supported ones — note the bug-prone ordering: 'm' alone is ambiguous with 'ms', and units like 'w' or 'y' are unsupported.","triggerScenarios":"DurationUtil.parse(\"10w\"), parse(\"5y\"), parse(\"3sec\"), or any value matching ^[+-]?\\d+[a-zA-Z]{1,2}$ whose letters are not ms/d/h/m/s — e.g. when a timeout property such as seata client RM/TM timeout configs is given an unsupported unit.","commonSituations":"Configuring seata timeouts (e.g. tm.degrade-check period, client heartbeat intervals) with 'w'/'y'/'hr' units; using java.time-style units like '30S' (uppercase S fails the unit tests since matching is case-sensitive); trailing whitespace trimmed to letters.","solutions":["Convert the value to a supported unit: ms, s, m, h, or d (e.g. 10w -> 70d).","Use exact ISO-8601 (PT168H) for unusual durations.","Bare numbers are milliseconds — make sure you did not intend seconds when writing '30' (write '30s' instead)."],"exampleFix":"# before\nseata.tm.degrade-check.period=10w\n\n# after\nseata.tm.degrade-check.period=70d","handlingStrategy":"validation","validationCode":"// Accept only the documented simple units before parsing\nprivate static final Pattern DURATION_OK = Pattern.compile(\"^[+-]?\\\\d+(ms|s|m|h|d)?$\");\nif (value != null && !value.isBlank() && !DURATION_OK.matcher(value).matches()\n        && !value.matches(\"^[+-]?P.*$\")) {\n    throw new IllegalArgumentException(\"Unsupported duration value: \" + value\n        + \" (use e.g. 30s, 5m, 2h, 7d, 2500ms, ISO-8601, or plain millis)\");\n}\nDuration d = DurationUtil.parse(value);","typeGuard":"boolean isSupportedSimpleUnit(String unit) {\n    return Set.of(\"ms\", \"s\", \"m\", \"h\", \"d\").contains(unit.toLowerCase());\n}","tryCatchPattern":"try {\n    Duration d = DurationUtil.parse(str);\n} catch (UnsupportedOperationException e) {\n    // message shows the exact string; map to a user-facing config error with valid examples\n    throw new IllegalArgumentException(\"Invalid duration '\" + str + \"'. Examples: 30s, 5m, 2h, 7d, 2500ms\", e);\n}","preventionTips":["Stick to ms/s/m/h/d units; there is no w or y.","Units are matched case-sensitively in practice — write lowercase to be safe.","A bare number means milliseconds; never assume seconds."],"tags":["configuration","duration","parsing","seata"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}