JetBrains/intellij-community · error · FormatDecode.IllegalFormatException

width (''{0}'') not allowed in ''{1}''

Error message

width (''{0}'') not allowed in ''{1}''

What it means

IllegalFormatException from FormatDecode when the %n (line separator) conversion is given a width, e.g. '%10n'. %n takes no flags, width, or precision; the decoder first zeroes allowed flags then explicitly rejects a non-empty width before also rejecting precision. Matches java.util.Formatter's runtime behavior statically.

Source

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

      int flagBits = 0;
      for (int j = 0; j < flags.length(); j++) {
        final char flag = flags.charAt(j);
        final int bit = flag(flag);
        if (bit == -1) {
          throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.unexpected.flag", flag, specifier));
        }
        if ((flagBits | bit) == flagBits) {
          throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.duplicate.flag", flag, specifier));
        }
        flagBits |= bit;
      }

      // check this first because it should not affect "implicit"
      if ("n".equals(conversion)) {
        // no flags allowed
        checkFlags(flagBits, 0, specifier);
        if (!StringUtil.isEmpty(width)) {
          throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.width.not.allowed", width, specifier));
        }
        checkNoPrecision(precision, specifier);
        continue;
      }
      else if ("%".equals(conversion)) { // literal '%'
        checkFlags(flagBits, LEFT_JUSTIFY, specifier);
        checkNoPrecision(precision, specifier);
        continue;
      }

      if (posSpec != null) {
        if (isAllBitsSet(flagBits, PREVIOUS)) {
          throw new IllegalFormatException(
            InspectionGadgetsBundle.message("format.string.error.unnecessary.position.specifier", posSpec, specifier));
        }
        final String num = posSpec.substring(0, posSpec.length() - 1);
        pos = Integer.parseInt(num) - 1;
        if (pos < 0) {

View on GitHub (pinned to be881553f2)

Solutions

  1. Remove the width from the %n specifier; use plain '%n'
  2. If you need padded output, use a literal newline via %s with a padded string or restructure the format

Example fix

// before
String.format("column%8n")
// after
String.format("column%n")
Defensive patterns

Strategy: validation

Validate before calling

static boolean widthAllowedFor(String conversion) {
  return !"n".equals(conversion); // %n forbids flags, width, and precision
}

Try / catch

try { FormatDecode.decode(fmt, argc); } catch (IllegalFormatException e) { /* strip width from the %n specifier */ }

Prevention

When it happens

Trigger: A format string containing '%<width>n' such as '%5n' or '%-8n'; width group non-empty while conversion equals 'n'.

Common situations: Padding attempts on platform line separators; template generators inserting widths for every placeholder; misunderstanding %n as a generic newline placeholder with printf-style padding.

Related errors


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