JetBrains/intellij-community · error · FormatDecode.IllegalFormatException
previous flag ''<'' used but no previous format specifier fo
Error message
previous flag ''<'' used but no previous format specifier found for ''{0}'' What it means
IllegalFormatException from FormatDecode when the '<' (previous argument) flag is used in a specifier but no previous argument reference exists — either it is the first specifier or the previous specifier could not establish a position. previousAllowed tracks whether a usable 'last position' exists; '<' requires one.
Source
Thrown at java/java-analysis-impl/src/com/siyeh/ig/format/FormatDecode.java:293
}
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) {
throw new IllegalFormatException(
InspectionGadgetsBundle.message("format.string.error.illegal.position.specifier", posSpec, specifier));
}
previousAllowed = true;
}
else if (isAllBitsSet(flagBits, PREVIOUS)) {
// reuse last pos
if (!previousAllowed) {
throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.previous.element.not.found", specifier));
}
}
else {
previousAllowed = true;
pos = implicit++;
}
final Validator allowed;
if (isAllVerifier) {
allowed = new AllValidatorWithRange(TextRange.create(matcher.start(), matcher.end()),
new Spec(posSpec, flags, width, precision, dateSpec, conversion));
}
else if (dateSpec != null) { // a t or T
checkFlags(flagBits, LEFT_JUSTIFY | PREVIOUS, specifier);
DateTimeConversionType dateTimeConversionType = getDateTimeConversionType(conversion.charAt(0));
if (dateTimeConversionType == DateTimeConversionType.UNKNOWN) {
throw new IllegalFormatException(
InspectionGadgetsBundle.message("format.string.error.unknown.conversion", dateSpec + conversion));View on GitHub (pinned to be881553f2)
Solutions
- Remove the '<' flag, or ensure an earlier specifier consumes an argument before it
- Replace '<' with an explicit 'N$' index for robustness
Example fix
// before
String.format("%<s", "a")
// after
String.format("%1$s", "a") Defensive patterns
Strategy: try-catch
Validate before calling
static boolean previousFlagLegal(String fmt) {
boolean prevAllowed = false;
for (String spec : fmt.split("(?<!%)%")) {
boolean hasPrev = spec.contains("<");
boolean indexed = spec.matches("\\d+\\$.*");
if (hasPrev && !prevAllowed && !indexed) return false;
prevAllowed = true; // any consuming specifier establishes a position
}
return true;
} Try / catch
try { FormatDecode.decode(fmt, argc); } catch (IllegalFormatException e) { /* replace leading '<' with explicit 'N$' */ } Prevention
- Avoid '<' in generated formats; explicit indices are safer
- After deleting the first specifier, strip any '<' from the following one
When it happens
Trigger: A format string starting with '%<s' (the '<' flag on the first specifier), or following a specifier type that did not set previousAllowed; decode hits PREVIOUS bit with previousAllowed == false.
Common situations: Deleting the first specifier from a format string and forgetting to strip '<' from the next; reorder/copy of specifiers leaving a leading relative-previous flag.
Related errors
- {2, choice, 1#flag|1<flags} ''{0}'' not allowed in ''{1}''
- unexpected character ''{0}'' in ''{1}''
- duplicate flag ''{0}'' in ''{1}''
- width (''{0}'') not allowed in ''{1}''
- unnecessary argument position specifier ''{0}'' in ''{1}''
AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14).
Data as JSON: /api/errors/cd460d88bcb9c16f.
Report an issue: GitHub.