{"record":{"id":"f2dbec87672d9ac3","repo":"SonarSource/sonarqube","slug":"failed-to-parse-duration-threshold-using-raw","errorCode":null,"errorMessage":"Failed to parse duration threshold: {}, using raw value instead","messagePattern":"Failed to parse duration threshold: (.+?), using raw value instead","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QualityGateConditionFormatter.java","lineNumber":105,"sourceCode":"    String translatedMetricName = getTranslatedMetricName(metricKey, metricName);\n    String operatorLabel = OPERATOR_LABELS.get(operator);\n    String formattedThreshold = formatThreshold(threshold, metricType);\n\n    return translatedMetricName + \" \" + operatorLabel + \" \" + formattedThreshold;\n  }\n\n  private String getTranslatedMetricName(String metricKey, @Nullable String defaultName) {\n    String fallback = defaultName != null ? defaultName : metricKey;\n    return i18n.message(Locale.ENGLISH, \"metric.\" + metricKey + \".name\", fallback);\n  }\n\n  private String formatThreshold(String threshold, @Nullable String metricType) {\n    if (Metric.ValueType.WORK_DUR.name().equals(metricType)) {\n      try {\n        long durationInSeconds = Long.parseLong(threshold);\n        return durations.format(Duration.create(durationInSeconds));\n      } catch (NumberFormatException e) {\n        LOGGER.warn(\"Failed to parse duration threshold: {}, using raw value instead\", threshold, e);\n      }\n    }\n    return threshold;\n  }\n\n}\n","sourceCodeStart":87,"sourceCodeEnd":112,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QualityGateConditionFormatter.java#L87-L112","documentation":"QualityGateConditionFormatter.formatThreshold logs this warning when a WORK_DUR (work duration) metric threshold cannot be parsed as a long number of minutes, and falls back to returning the raw threshold string in the notification text. Formatting continues; only the human-readable duration formatting is skipped.","triggerScenarios":"formatThreshold is called with metricType WORK_DUR and a threshold string where Long.parseLong(threshold) throws NumberFormatException — e.g. '2d', '1h30', 'abc', or an empty string stored in the condition's warning/error threshold.","commonSituations":"A quality gate condition was created/edited via the web API with a non-numeric threshold for a WORK_DUR metric like 'reliability remediation effort'; data imported from a modified DB; locale-prefixed values pasted into the UI.","solutions":["Fix the quality gate condition so its threshold is a plain integer number of minutes (e.g. '30', '480')","Re-create the condition via UI or api/qualitygates/update with a numeric value","If you own the calling code, validate the threshold parses before setting it on the condition"],"exampleFix":"// before\nsetCondition(metric=\"new_reliability_rating_effort\", threshold=\"2d\");\n// after\nsetCondition(metric=\"new_reliability_rating_effort\", threshold=\"480\"); // minutes","handlingStrategy":"validation","validationCode":"long threshold;\ntry {\n  threshold = Long.parseLong(rawThreshold);\n} catch (NumberFormatException e) {\n  throw new IllegalArgumentException(\"WORK_DUR condition threshold must be an integer number of minutes, got: \" + rawThreshold);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set WORK_DUR condition thresholds as plain minute values via the UI or API","Never paste duration strings like '2d' or '1h' into threshold fields","Add API-side checks in tooling that creates quality gate conditions"],"tags":["qualitygate","parsing","sonarqube","configuration"],"backgroundTag":"invalid-number-format","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}