{"record":{"id":"cd460d88bcb9c16f","repo":"JetBrains/intellij-community","slug":"previous-flag-used-but-no-previous-format-sp","errorCode":null,"errorMessage":"previous flag ''<'' used but no previous format specifier found for ''{0}''","messagePattern":"previous flag ''<'' used but no previous format specifier found for ''(.+?)''","errorType":"exception","errorClass":"FormatDecode.IllegalFormatException","httpStatus":null,"severity":"error","filePath":"java/java-analysis-impl/src/com/siyeh/ig/format/FormatDecode.java","lineNumber":293,"sourceCode":"      }\n\n      if (posSpec != null) {\n        if (isAllBitsSet(flagBits, PREVIOUS)) {\n          throw new IllegalFormatException(\n            InspectionGadgetsBundle.message(\"format.string.error.unnecessary.position.specifier\", posSpec, specifier));\n        }\n        final String num = posSpec.substring(0, posSpec.length() - 1);\n        pos = Integer.parseInt(num) - 1;\n        if (pos < 0) {\n          throw new IllegalFormatException(\n            InspectionGadgetsBundle.message(\"format.string.error.illegal.position.specifier\", posSpec, specifier));\n        }\n        previousAllowed = true;\n      }\n      else if (isAllBitsSet(flagBits, PREVIOUS)) {\n        // reuse last pos\n        if (!previousAllowed) {\n          throw new IllegalFormatException(InspectionGadgetsBundle.message(\"format.string.error.previous.element.not.found\", specifier));\n        }\n      }\n      else {\n        previousAllowed = true;\n        pos = implicit++;\n      }\n\n      final Validator allowed;\n      if (isAllVerifier) {\n        allowed = new AllValidatorWithRange(TextRange.create(matcher.start(), matcher.end()),\n                                            new Spec(posSpec, flags, width, precision, dateSpec, conversion));\n      }\n      else if (dateSpec != null) {  // a t or T\n        checkFlags(flagBits, LEFT_JUSTIFY | PREVIOUS, specifier);\n        DateTimeConversionType dateTimeConversionType = getDateTimeConversionType(conversion.charAt(0));\n        if (dateTimeConversionType == DateTimeConversionType.UNKNOWN) {\n          throw new IllegalFormatException(\n            InspectionGadgetsBundle.message(\"format.string.error.unknown.conversion\", dateSpec + conversion));","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/JetBrains/intellij-community/blob/be881553f2a76ac8b4ea53950d93f0de78295c19/java/java-analysis-impl/src/com/siyeh/ig/format/FormatDecode.java#L275-L311","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove the '<' flag, or ensure an earlier specifier consumes an argument before it","Replace '<' with an explicit 'N$' index for robustness"],"exampleFix":"// before\nString.format(\"%<s\", \"a\")\n// after\nString.format(\"%1$s\", \"a\")","handlingStrategy":"try-catch","validationCode":"static boolean previousFlagLegal(String fmt) {\n  boolean prevAllowed = false;\n  for (String spec : fmt.split(\"(?<!%)%\")) {\n    boolean hasPrev = spec.contains(\"<\");\n    boolean indexed = spec.matches(\"\\\\d+\\\\$.*\");\n    if (hasPrev && !prevAllowed && !indexed) return false;\n    prevAllowed = true; // any consuming specifier establishes a position\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try { FormatDecode.decode(fmt, argc); } catch (IllegalFormatException e) { /* replace leading '<' with explicit 'N$' */ }","preventionTips":["Avoid '<' in generated formats; explicit indices are safer","After deleting the first specifier, strip any '<' from the following one"],"tags":["intellij","format-string","inspection","java","parsing"],"backgroundTag":null,"analyzedSha":"be881553f2a76ac8b4ea53950d93f0de78295c19","analyzedAt":"2026-08-14T14:13:06.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}