bazelbuild/bazel · error · MissingFormatWidthException

not enough arguments for format pattern %s: %s

Error message

not enough arguments for format pattern %s: %s

What it means

Thrown by %-formatting when the pattern contains more conversion specifiers than there are arguments. Each conversion (other than %%) consumes one argument; when the argument index reaches argLength the printer raises MissingFormatWidthException with the pattern repr and the argument tuple repr.

Source

Thrown at src/main/java/net/starlark/java/eval/Printer.java:414

      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));
      }
      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) {

View on GitHub (pinned to e6e199d060)

Solutions

  1. Match the count: every %s/%d/%r/%x/... needs exactly one argument — add the missing value.
  2. Remember a single argument must still be a tuple for multi-field patterns: "%s %s" % (a, b).
  3. Consider named fields via format() when argument lists get long.

Example fix

# before
"%s=%s" % key  # key is one string

# after
"%s=%s" % (k, v)
Defensive patterns

Strategy: validation

Validate before calling

# count specifiers vs arguments before formatting
def count_specs(p):
    n = 0
    i = 0
    while i < len(p):
        if p[i] == "%" and i + 1 < len(p):
            if p[i+1] != "%":
                n += 1
            i += 2
        else:
            i += 1
    return n

assert count_specs(pattern) == len(args)

Prevention

When it happens

Trigger: "%s %s" % (1,), "%d/%d" % (num,), or passing a non-tuple single value where multiple are needed (note "%s %s" % "ab" treats the string as one arg and fails).

Common situations: Editing a message template to add a field but forgetting to add the value; passing a single value instead of a 1-tuple when a second field exists; refactoring that removes an argument but leaves its specifier.

Related errors


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