bazelbuild/bazel · error · MixedTypeException

Cannot mix manual and automatic numbering of positional fiel

Error message

Cannot mix manual and automatic numbering of positional fields

What it means

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.

Source

Thrown at src/main/java/net/starlark/java/eval/FormatParser.java:290

      setPositional(Positional.MANUAL);
    }

    /** Registers an automatic positional replacement field */
    void setAutomaticPositional() throws MixedTypeException {
      setPositional(Positional.AUTOMATIC);
    }

    /**
     * Indicates that a positional replacement field of the specified type is being processed and
     * checks whether this conflicts with any previously seen replacement fields
     *
     * @param current Type of current replacement field
     */
    void setPositional(Positional current) throws MixedTypeException {
      if (type == Positional.NONE) {
        type = current;
      } else if (type != current) {
        throw new MixedTypeException();
      }
    }
  }
}

View on GitHub (pinned to e6e199d060)

Solutions

  1. Pick one style per pattern: use only automatic fields "{} {}" or only manual ones "{0} {1}".
  2. If reordering is needed (e.g. for i18n), number ALL fields explicitly.
  3. Run the format string through a lint/test before shipping the rule.

Example fix

# before
"{0} scored {} points".format(name, pts)

# after
"{0} scored {1} points".format(name, pts)
Defensive patterns

Strategy: validation

Validate before calling

# reject patterns that mix {} and {N}
def check_format(pat):
    import re  # only where available; else manual scan
    has_auto = "{}" in pat
    has_manual = re.search(r"\{\d+\}", pat) != None
    if has_auto and has_manual:
        fail("format pattern mixes automatic and manual numbering: %r" % pat)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14). Data as JSON: /api/errors/c087129a8dc13844. Report an issue: GitHub.