JetBrains/intellij-community · error · FormatDecode.IllegalFormatException
unexpected character ''{0}'' in ''{1}''
Error message
unexpected character ''{0}'' in ''{1}'' What it means
IllegalFormatException from FormatDecode when a flag character inside a format specifier is not recognized at all — flag(flag) returned -1. Recognized flags are '-','#','+',' ','0',',' and '('; anything else in the flags region (which the regex may capture loosely, e.g. letters) triggers this. It is the 'unexpected character' variant, distinct from disallowed-but-known flags.
Source
Thrown at java/java-analysis-impl/src/com/siyeh/ig/format/FormatDecode.java:253
//theoretically, it could be a correct specifier, divided into several parts, for example: "%1$t" + "Y"
//it is better to add ALL_VERIFIER
if (noVerify || isPrefix && i == formatString.length()) {
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 '%'View on GitHub (pinned to be881553f2)
Solutions
- Correct the specifier to use only legal flags: '- # + 0 , ('
- Escape literal percent as '%%' instead of a malformed specifier
- Re-run the inspection after fixing to catch follow-on errors
Example fix
// before
String.format("%=5d", 42)
// after
String.format("%5d", 42) Defensive patterns
Strategy: validation
Validate before calling
private static final Set<Character> KNOWN_FLAGS = Set.of('-', '#', '+', ' ', '0', ',', '(');
static boolean flagsRecognized(String flags) {
return flags.chars().allMatch(c -> KNOWN_FLAGS.contains((char) c));
} Try / catch
try { FormatDecode.decode(fmt, argc); } catch (IllegalFormatException e) { /* point at the specifier containing the unknown character */ } Prevention
- Use only '- # + 0 , (' as flags
- Escape literal text and '%' correctly ('%%') instead of leaving stray characters
When it happens
Trigger: A specifier whose flags area contains an unrecognized character, e.g. '%=5d' or '%l5d'; typically from typos or regex-loose matching of malformed specifiers during decode().
Common situations: Typos in format strings; converting from other format dialects (MessageFormat, python) leaving stray characters; smart-quote corruption when pasting.
Related errors
- {2, choice, 1#flag|1<flags} ''{0}'' not allowed in ''{1}''
- duplicate flag ''{0}'' in ''{1}''
- width (''{0}'') not allowed in ''{1}''
- unnecessary argument position specifier ''{0}'' in ''{1}''
- previous flag ''<'' used but no previous format specifier fo
AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14).
Data as JSON: /api/errors/f1f939a0b66c7d43.
Report an issue: GitHub.