bazelbuild/bazel · error · OptionsParsingException

Must be in the form of a 'key=value[,value]' assignment

Error message

Must be in the form of a 'key=value[,value]' assignment

What it means

Thrown by AssignmentToListOfValuesConverter when the input has no '=' (or '=' at position 0) AND the converter was constructed with AllowEmptyKeys.NO. This converter parses key=value[,value...] assignments where the value side is a comma-separated list; the key must be present and non-empty when empty keys are disallowed.

Source

Thrown at src/main/java/com/google/devtools/common/options/Converters.java:576

    private static final Splitter SPLITTER = Splitter.on(',');

    private final Converter<K> keyConverter;
    private final Converter<V> valueConverter;
    private final AllowEmptyKeys allowEmptyKeys;

    public AssignmentToListOfValuesConverter(
        Converter<K> keyConverter, Converter<V> valueConverter, AllowEmptyKeys allowEmptyKeys) {
      this.keyConverter = keyConverter;
      this.valueConverter = valueConverter;
      this.allowEmptyKeys = allowEmptyKeys;
    }

    @Override
    public Map.Entry<K, List<V>> convert(String input, @Nullable Object conversionContext)
        throws OptionsParsingException {
      int pos = input.indexOf("=");
      if (allowEmptyKeys == AllowEmptyKeys.NO && pos <= 0) {
        throw new OptionsParsingException(
            "Must be in the form of a 'key=value[,value]' assignment");
      }

      String key = pos <= 0 ? "" : input.substring(0, pos);
      List<String> values = SPLITTER.splitToList(input.substring(pos + 1));
      if (values.contains("")) {
        // If the list contains exactly the empty string, it means an empty value was passed and we
        // should instead return an empty list.
        if (values.size() == 1) {
          values = ImmutableList.of();
        } else {
          throw new OptionsParsingException(
              "Variable definitions must not contain empty strings or leading / trailing commas");
        }
      }
      ImmutableList.Builder<V> convertedValues = ImmutableList.builder();
      for (String value : values) {
        convertedValues.add(valueConverter.convert(value, conversionContext));

View on GitHub (pinned to e6e199d060)

Solutions

  1. Supply the full assignment including '=' and at least one value: --flag=key=value or --flag=key=v1,v2.
  2. If an empty key is legitimately required, check whether the flag's converter was built with AllowEmptyKeys.YES and use the correct flag instead.
  3. Validate generated values with a regex like ^.+=(.+,.*)*$ before passing them to the command line.

Example fix

# before
--test_filter=foo

# after
--test_filter=foo=bar,baz
Defensive patterns

Strategy: validation

Validate before calling

// Validate key=value[,value] shape before passing to a map-of-lists flag
boolean isValidKeyedList(String s) {
  if (s == null) return false;
  int pos = s.indexOf("=");
  return pos > 0; // AllowEmptyKeys.NO requires non-empty key
}

Try / catch

Catch OptionsParsingException around the parse call; report the flag name and raw value so the offending assignment can be located in scripts or rc files.

Prevention

When it happens

Trigger: Passing a value like 'JUST_A_KEY' or '=a,b' to a flag whose converter was built with AllowEmptyKeys.NO (pos <= 0 fails). The converter is generic — used for option types declared as Map<K, List<V>> with list-valued assignments, e.g. --per_file_copt-style or test filter flags that take key=v1,v2.

Common situations: Omitting the '=' when passing a list-valued map flag, copy-pasting a flag example and dropping '=value', script-generated flag values that emit only the key when a lookup fails, migrating a flag from single-value to list-value semantics.

Related errors


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