bazelbuild/bazel · error · OptionsParsingException

Illegal duration '" + input + "'.

Error message

Illegal duration '" + input + "'.

What it means

Thrown by Converters.DurationConverter.convert when the input does not match the regex ^([0-9]+)(d|h|m|s|ms|ns)$ and is not the special bare value "0". Bazel durations are integer amounts with a single lowercase unit; fractional values and missing/unknown units are rejected with an OptionsParsingException.

Source

Thrown at src/main/java/com/google/devtools/common/options/Converters.java:215

    @Override
    public String getTypeDescription() {
      return "";
    }
  }

  /** Standard converter for the {@link java.time.Duration} type. */
  public static class DurationConverter extends Converter.Contextless<Duration> {
    private static final Pattern DURATION_REGEX = Pattern.compile("^([0-9]+)(d|h|m|s|ms|ns)$");

    @Override
    public Duration convert(String input) throws OptionsParsingException {
      // To be compatible with the previous parser, '0' doesn't need a unit.
      if ("0".equals(input)) {
        return Duration.ZERO;
      }
      Matcher m = DURATION_REGEX.matcher(input);
      if (!m.matches()) {
        throw new OptionsParsingException("Illegal duration '" + input + "'.");
      }
      long duration = Long.parseLong(m.group(1));
      String unit = m.group(2);
      switch (unit) {
        case "d":
          return Duration.ofDays(duration);
        case "h":
          return Duration.ofHours(duration);
        case "m":
          return Duration.ofMinutes(duration);
        case "s":
          return Duration.ofSeconds(duration);
        case "ms":
          return Duration.ofMillis(duration);
        case "ns":
          return Duration.ofNanos(duration);
        default:
          throw new IllegalStateException(

View on GitHub (pinned to e6e199d060)

Solutions

  1. Write an integer count plus one lowercase unit: e.g. 90s, 5m, 2h, 1d, 500ms, 100ns.
  2. Normalize compound durations yourself: 1m30s -> 90s.
  3. Zero can be written bare as 0.

Example fix

# before
bazel test --test_timeout=1m30s //...
# after
bazel test --test_timeout=90s //...
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern OK = Pattern.compile("^([0-9]+)(d|h|m|s|ms|ns)$");

boolean isParsableDuration(String s) {
  return "0".equals(s) || (s != null && OK.matcher(s).matches());
}

Type guard

boolean isDurationFlagValue(String s) {
  return s != null && (s.equals("0") || s.matches("[0-9]+(d|h|m|s|ms|ns)"));
}

Prevention

When it happens

Trigger: Passing --timeout=100 (no unit), --timeout=1.5s (fraction), --timeout=1D or --timeout=1H (uppercase), --timeout=1hr, --timeout=1us (unsupported unit) to any Duration-typed option using this converter.

Common situations: Coming from tools that accept bare seconds or ISO-8601 durations ("PT2H", "2h30m"); compounding units like "1m30s" which the single-unit regex rejects; uppercase or abbreviated units (us instead of ns).

Related errors


AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14). Data as JSON: /api/errors/dbe1d3e075b8e577. Report an issue: GitHub.