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
- Write an integer count plus one lowercase unit: e.g. 90s, 5m, 2h, 1d, 500ms, 100ns.
- Normalize compound durations yourself: 1m30s -> 90s.
- 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
- Always attach a lowercase unit; bare numbers other than 0 are rejected.
- Compound durations (1m30s) are invalid: pre-compute a single unit value.
- Use ns not us for sub-millisecond values.
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
- '" + input + "' is not a boolean
- '" + input + "' is not an int
- '" + input + "' is not a long
- '" + input + "' is not a double
- Not a valid %s: '%s' (should be auto or a boolean)
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/dbe1d3e075b8e577.
Report an issue: GitHub.