{"record":{"id":"c087129a8dc13844","repo":"bazelbuild/bazel","slug":"cannot-mix-manual-and-automatic-numbering-of-posit","errorCode":null,"errorMessage":"Cannot mix manual and automatic numbering of positional fields","messagePattern":"Cannot mix manual and automatic numbering of positional fields","errorType":"exception","errorClass":"MixedTypeException","httpStatus":null,"severity":"error","filePath":"src/main/java/net/starlark/java/eval/FormatParser.java","lineNumber":290,"sourceCode":"      setPositional(Positional.MANUAL);\n    }\n\n    /** Registers an automatic positional replacement field */\n    void setAutomaticPositional() throws MixedTypeException {\n      setPositional(Positional.AUTOMATIC);\n    }\n\n    /**\n     * Indicates that a positional replacement field of the specified type is being processed and\n     * checks whether this conflicts with any previously seen replacement fields\n     *\n     * @param current Type of current replacement field\n     */\n    void setPositional(Positional current) throws MixedTypeException {\n      if (type == Positional.NONE) {\n        type = current;\n      } else if (type != current) {\n        throw new MixedTypeException();\n      }\n    }\n  }\n}\n","sourceCodeStart":272,"sourceCodeEnd":295,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/net/starlark/java/eval/FormatParser.java#L272-L295","documentation":"Thrown by Starlark's str.format-style parser (FormatParser) when a single pattern mixes automatic field numbering ({}, {}) and manual numbering ({0}, {1}). The parser tracks which positional style it has seen; setPositional raises MixedTypeException when the current field's style differs from the previous one.","triggerScenarios":"Calling a format-enabled builtin with a pattern like \"{} {0}\" or \"{1} and {}\" — i.e. any string that contains both bare braces and indexed braces in one pattern.","commonSituations":"Copy-pasting a Python format string that mixed styles; incrementally editing a message template and adding an index to one field while leaving others bare; translation/localization strings where one field got manually numbered.","solutions":["Pick one style per pattern: use only automatic fields \"{} {}\" or only manual ones \"{0} {1}\".","If reordering is needed (e.g. for i18n), number ALL fields explicitly.","Run the format string through a lint/test before shipping the rule."],"exampleFix":"# before\n\"{0} scored {} points\".format(name, pts)\n\n# after\n\"{0} scored {1} points\".format(name, pts)","handlingStrategy":"validation","validationCode":"# reject patterns that mix {} and {N}\ndef check_format(pat):\n    import re  # only where available; else manual scan\n    has_auto = \"{}\" in pat\n    has_manual = re.search(r\"\\{\\d+\\}\", pat) != None\n    if has_auto and has_manual:\n        fail(\"format pattern mixes automatic and manual numbering: %r\" % pat)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Adopt a repo convention: always number fields explicitly ({0}, {1}).","Run format strings through a smoke test in CI."],"tags":["starlark","format","str-format","mixed-numbering"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}