bazelbuild/bazel · error · MissingFormatWidthException
got %s, want a finite number
Error message
got %s, want a finite number
What it means
Thrown by %d/%o/%x/%X formatting when the argument is a StarlarkFloat that is infinite or NaN. The printer tries StarlarkInt.ofFiniteDouble to coerce the float to an integer; ofFiniteDouble rejects non-finite/non-integral-representable doubles with IllegalArgumentException, which is converted to this MissingFormatWidthException.
Source
Thrown at src/main/java/net/starlark/java/eval/Printer.java:433
"not enough arguments for format pattern "
+ Starlark.repr(pattern, semantics)
+ ": "
+ Starlark.repr(Tuple.copyOf(arguments), semantics));
}
Object arg = arguments.get(a++);
switch (conv) {
case 'd', 'o', 'x', 'X' -> {
Number n =
switch (arg) {
case StarlarkInt starlarkInt -> starlarkInt.toNumber();
case Integer integer -> integer;
case StarlarkFloat starlarkFloat -> {
double d = starlarkFloat.toDouble();
try {
yield StarlarkInt.ofFiniteDouble(d).toNumber();
} catch (IllegalArgumentException unused) {
throw new MissingFormatWidthException("got " + arg + ", want a finite number");
}
}
default ->
throw new MissingFormatWidthException(
String.format(
"got %s for '%%%c' format, want int or float",
Starlark.type(arg), conv));
};
printer.append(
String.format(
conv == 'd' ? "%d" : conv == 'o' ? "%o" : conv == 'x' ? "%x" : "%X", n));
}
case 'e', 'f', 'g', 'E', 'F', 'G' -> {
double v =
switch (arg) {
case Integer integer -> (double) integer;
case StarlarkInt starlarkInt -> starlarkInt.toDouble();View on GitHub (pinned to e6e199d060)
Solutions
- Use a float conversion (%f/%g/%e) instead of %d for non-integral or possibly non-finite values.
- Sanitize before formatting: replace non-finite values (v == v and abs(v) != float("inf")) with 0 or a sentinel.
- Fix the upstream computation that produced inf/nan (guard divisors, check for zero denominators).
Example fix
# before "%d items" % (total / count) # count can be 0 -> inf/nan # after "%g items" % (total / count) if count else "n/a"
Defensive patterns
Strategy: validation
Validate before calling
def finite_int(v):
if type(v) == "float" and (v != v or v == float("inf") or v == float("-inf")):
fail("non-finite value for %d: %s" % (type(v), v))
return v
"%d" % finite_int(x) Type guard
def is_finite_number(v):
return type(v) == "int" or (type(v) == "float" and v == v and v != float("inf") and v != float("-inf")) Prevention
- Guard divisors before computing ratios that feed %d.
- Use %g/%f for anything that may legitimately be non-integral or non-finite.
When it happens
Trigger: "%d" % float("inf"), "%x" % float("nan"), "%d" % (1e300 / 1e300 * float('nan')), or any arithmetic that yields inf/nan (division overflows, float("1e400")) followed by %d formatting.
Common situations: Formatting computed ratios or scores that can divide by zero; parsing user input like 'inf'/'nan' with float(); JSON-decoded floats carrying NaN before %d logging.
Related errors
- Cannot mix manual and automatic numbering of positional fiel
- incomplete format pattern ends with %: %s
- not enough arguments for format pattern %s: %s
- got %s for '%%%c' format, want int or float
- unsupported format character "%s" at index %s in %s
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/06c4a727f9292b27.
Report an issue: GitHub.