JetBrains/intellij-community · error · FormatDecode.IllegalFormatException

duplicate flag ''{0}'' in ''{1}''

Error message

duplicate flag ''{0}'' in ''{1}''

What it means

IllegalFormatException from FormatDecode when the same flag appears twice in one specifier — detected by (flagBits | bit) == flagBits, i.e. the bit was already set. java.util.Formatter likewise rejects duplicate flags ('Duplicate format flag %s in format string'). The inspection reports it statically at the flagged specifier.

Source

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

        isAllVerifier = true;
      }
      final String specifier = matcher.group();
      final String posSpec = matcher.group("posSpec");
      final String flags = matcher.group("flags");
      final String width = matcher.group("width");
      final String precision = matcher.group("precision");
      final String dateSpec = matcher.group("dateSpec");
      final @NonNls String conversion = matcher.group("conversion");

      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;

View on GitHub (pinned to be881553f2)

Solutions

  1. Deduplicate flags in the specifier (keep one occurrence)
  2. If building format strings dynamically, track applied flags in a Set before appending

Example fix

// before
String.format("%--5s", "x")
// after
String.format("%-5s", "x")
Defensive patterns

Strategy: validation

Validate before calling

static boolean noDuplicateFlags(String flags) {
  return flags.chars().distinct().count() == flags.length();
}

Try / catch

try { FormatDecode.decode(fmt, argc); } catch (IllegalFormatException e) { /* report duplicated flag character */ }

Prevention

When it happens

Trigger: Specifiers like '%--5s', '%00d', '%,,f'; decode() iterates the flag characters and re-setting an already-set bit throws.

Common situations: Concatenating flag strings programmatically so a flag is appended twice; copy-paste edits duplicating a character; regex-built formats in logging wrappers.

Related errors


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