bazelbuild/bazel · error · MissingFormatWidthException

unsupported format character "%s" at index %s in %s

Error message

unsupported format character "%s" at index %s in %s

What it means

Thrown by %-formatting when the character after % is not a recognized conversion. Starlark supports %% %s %r %d %o %x %X %e %f %g %E %F %G (no flags, width, or precision except in the float conversions handled separately); anything else — %i, %y, % , or a letter like %n — hits the default branch and reports the offending character, its index, and the whole pattern repr.

Source

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

                case StarlarkInt starlarkInt -> starlarkInt.toDouble();
                case StarlarkFloat starlarkFloat -> starlarkFloat.toDouble();
                default ->
                    throw new MissingFormatWidthException(
                        String.format(
                            "got %s for '%%%c' format, want int or float",
                            Starlark.type(arg), conv));
              };
          printer.append(StarlarkFloat.format(v, conv));
        }

        case 'r' -> printer.repr(arg, semantics);

        case 's' -> printer.str(arg, semantics);

        default ->
            // The call to Starlark.repr doesn't cause an infinite recursion
            // because it's only used to format a string properly.
            throw new MissingFormatWidthException(
                String.format(
                    "unsupported format character \"%s\" at index %s in %s",
                    conv, p + 1, Starlark.repr(pattern, semantics)));
      }
    }
    if (a < argLength) {
      throw new MissingFormatWidthException("not all arguments converted during string formatting");
    }
  }
}

View on GitHub (pinned to e6e199d060)

Solutions

  1. Replace the unsupported specifier: %i -> %d, %b -> %s, %n -> newline via concatenation.
  2. Do formatting of widths/padding in Starlark code (e.g. (" " + s)[-10:]) or pre-format in Java.
  3. Test every literal pattern once; unsupported characters fail deterministically on first call.

Example fix

# before
"items: %i, done: %b" % (n, ok)

# after
"items: %d, done: %s" % (n, ok)
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = set("%srdoxXefgEFG")
def check_pattern(p):
    i = 0
    while i < len(p):
        if p[i] == "%":
            if i + 1 >= len(p):
                fail("trailing %")
            if p[i+1] not in ALLOWED:
                fail("bad conversion %%%s" % p[i+1])
            i += 2
        else:
            i += 1

Prevention

When it happens

Trigger: "%i" % 5, "100%n" % (), "%y" % x, "% d" % 1 (space flag is not supported), or copying a Java/Python pattern using unsupported specifiers or flags.

Common situations: Porting Java format strings (%n, %b, width/flag specifiers) or C-style patterns into Starlark; writers assuming Python's full printf grammar including flags like %-10s.

Related errors


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