JetBrains/intellij-community · error · FormatDecode.IllegalFormatException

left justify flag ''-'' used but width not specified in ''{0

Error message

left justify flag ''-'' used but width not specified in ''{0}''

What it means

Thrown when a format specifier uses the left-justify flag '-' but specifies no field width. Left justification only has meaning relative to a width (pad the field on the right up to N characters), so java.util.Formatter rejects '-' without a width; FormatDecode encodes the same rule (LEFT_JUSTIFY set while the parsed width string is empty) for the InspectionGadgets format-string checks.

Source

Thrown at java/java-analysis-impl/src/com/siyeh/ig/format/FormatDecode.java:371

          case 'f' -> // floating point -> decimal number
            allowed = new FloatValidator(specifier);
          default -> throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.unknown.conversion", specifier));
        }
      }
      if (precision != null && precision.length() < 2) {
        throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.invalid.precision", specifier));
      }
      if (isAllBitsSet(flagBits, LEADING_SPACE | PLUS)) {
        throw new IllegalFormatException(
          InspectionGadgetsBundle.message("format.string.error.illegal.flag.combination", ' ', '+', specifier));
      }
      if (isAllBitsSet(flagBits, LEFT_JUSTIFY | ZERO_PAD)) {
        throw new IllegalFormatException(
          InspectionGadgetsBundle.message("format.string.error.illegal.flag.combination", '-', '0', specifier));
      }
      if (StringUtil.isEmpty(width)) {
        if (isAllBitsSet(flagBits, LEFT_JUSTIFY)) {
          throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.left.justify.no.width", specifier));
        }
        if (isAllBitsSet(flagBits, ZERO_PAD)) {
          throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.zero.padding.no.width", specifier));
        }
      }
      storeValidator(allowed, pos, parameters, argumentCount);
    }
    if (i < formatString.length()) {
      String endString = formatString.substring(i);
      if (!isPrefix) {
        checkText(endString);
      }
      else {
        //only case, when fsPattern doesn't find a specifier, is when there is no any conversion.
        //add "s" as a random reasonable conversion
        String suggestedString = endString + "s";
        Matcher endMatcher = fsPattern.matcher(suggestedString);
        if (!endMatcher.find() || endMatcher.end() != suggestedString.length()) {

View on GitHub (pinned to be881553f2)

Solutions

  1. Add an explicit width, e.g. "%-10s", if you actually want left-justified padding.
  2. Remove the '-' flag, e.g. "%s", if alignment does not matter.
  3. If the width is computed at runtime, make sure the width segment is only omitted together with the '-' flag.

Example fix

// before
String s = String.format("%-s", "hi");

// after
String s = String.format("%-10s", "hi");
Defensive patterns

Strategy: validation

Validate before calling

static void checkJustifyHasWidth(String fmt) {
  java.util.regex.Matcher m = java.util.regex.Pattern.compile("%(-)?(\d+)?[a-zA-Z]").matcher(fmt);
  while (m.find()) {
    if ("-".equals(m.group(1)) && m.group(2) == null) throw new IllegalArgumentException("'-' without width: " + m.group());
  }
}

Prevention

When it happens

Trigger: A specifier like "%-d" or "%-s" — the '-' flag present, but no numeric width between the flags and the conversion character — in a format string decoded by FormatDecode.

Common situations: A width digit accidentally deleted during refactoring; dynamically assembled specifiers where the width component is conditionally empty; template strings copied with a truncated specifier.

Related errors


AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14). Data as JSON: /api/errors/d04b6a9d99cb0ad0. Report an issue: GitHub.