bazelbuild/bazel · error · MissingFormatWidthException
incomplete format pattern ends with %: %s
Error message
incomplete format pattern ends with %: %s
What it means
Thrown by Starlark's printf-style %-formatting (Printer.formatString) when the pattern's last character is a lone '%'. A trailing % is treated as the start of a conversion but has no conversion character, so formatting aborts with MissingFormatWidthException carrying 'incomplete format pattern ends with %: <repr of pattern>'.
Source
Thrown at src/main/java/net/starlark/java/eval/Printer.java:400
// whose constructor can take and display arbitrary error message, hence its use below.
// TODO(adonovan): this suggests we're using the wrong exception. Throw IAE?
int length = pattern.length();
int argLength = arguments.size();
int i = 0; // index of next character in pattern
int a = 0; // index of next argument in arguments
while (i < length) {
int p = pattern.indexOf('%', i);
if (p == -1) {
printer.append(pattern, i, length);
break;
}
if (p > i) {
printer.append(pattern, i, p);
}
if (p == length - 1) {
throw new MissingFormatWidthException(
"incomplete format pattern ends with %: " + Starlark.repr(pattern, semantics));
}
char conv = pattern.charAt(p + 1);
i = p + 2;
// %%: literal %
if (conv == '%') {
printer.append('%');
continue;
}
// get argument
if (a >= argLength) {
throw new MissingFormatWidthException(
"not enough arguments for format pattern "
+ Starlark.repr(pattern, semantics)
+ ": "
+ Starlark.repr(Tuple.copyOf(arguments), semantics));View on GitHub (pinned to e6e199d060)
Solutions
- Escape the literal percent: use %% wherever a literal % is wanted, including at the end.
- Prefer str.format-style or plain concatenation for text containing many literal percent signs.
- Lint format patterns for a trailing single % before use.
Example fix
# before msg = "progress: %d%" % pct # after msg = "progress: %d%%" % pct
Defensive patterns
Strategy: validation
Validate before calling
def fmt(pattern):
if pattern.endswith("%") and not pattern.endswith("%%"):
fail("pattern ends with lone %: %r" % pattern)
return pattern Prevention
- Always write literal percent as %% in %-format strings.
- Prefer str.format or concatenation for text dense with % signs.
When it happens
Trigger: "100%" % (), "rate: %s%%" works but "rate: %s%" % (x,) fails; any pattern built by concatenation that leaves a single % at the end, e.g. "%s" + "%".
Common situations: Building human-readable messages with percentages ('completed 50%'); concatenating a variable suffix onto a format string; templates authored by non-Python users who don't know % must be doubled.
Related errors
- 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
- not all arguments converted during string formatting
- Cannot mix manual and automatic numbering of positional fiel
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/8286cf309863430f.
Report an issue: GitHub.