bazelbuild/bazel · error · OptionsParsingException

Variable definitions must not contain empty strings or leadi

Error message

Variable definitions must not contain empty strings or leading / trailing commas

What it means

Thrown by AssignmentToListOfValuesConverter when the comma-separated value list contains an empty string in a position other than being the sole element (a lone empty value is treated as an empty list). This happens when the input has adjacent commas (e.g. 'a,,b'), a trailing comma before '=' splitting ('a=b,'), or a leading comma ('a=,b').

Source

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

    @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));
      }
      return Maps.immutableEntry(
          keyConverter.convert(key, conversionContext), convertedValues.build());
    }
  }

  /**
   * A converter for variable assignments from the parameter list of a blaze command invocation.
   * Assignments are expected to have the form {@code [name=]value1[,..,valueN]}, where names and
   * values are defined to be as permissive as possible. If no name is provided, "" is used.
   */
  public static class StringToStringListConverter

View on GitHub (pinned to e6e199d060)

Solutions

  1. Remove leading/trailing/double commas from the value list: --flag=key=v1,v2 not --flag=key=v1,,v2 or --flag=key=v1,.
  2. In generating code, filter out empty segments before joining: parts.stream().filter(p -> !p.isEmpty()).collect(joining(",")).
  3. To pass an explicitly empty list, use key= alone (a single empty value maps to an empty list) rather than key=, .

Example fix

# before
--per_file_copt=//foo/.*=,-O2

# after
--per_file_copt=//foo/.*=-O2
Defensive patterns

Strategy: validation

Validate before calling

// Reject empty segments before the parser does
boolean hasNoEmptySegments(String s) {
  int pos = s.indexOf("=");
  if (pos < 0) return false;
  for (String part : s.substring(pos + 1).split(",", -1)) {
    if (part.isEmpty() && !s.substring(pos + 1).isEmpty()) return false;
  }
  return true;
}

Try / catch

Catch OptionsParsingException and include the raw flag value in logs; the parser error does not echo the input, so caller-side logging is essential.

Prevention

When it happens

Trigger: Input whose value side splits on ',' into a list containing "" plus other elements: key=,v / key=v, / key=v,,w passed to any flag using AssignmentToListOfValuesConverter. Note pos + 1 substring: if input ends right after '=', values == [""] which is allowed (empty list).

Common situations: Trailing commas from joining script arrays (String.join(",", parts) with a trailing empty element), copy-paste edits leaving double commas, environment variables that expand to empty inside a comma list, config generators concatenating optional segments without filtering blanks.

Related errors


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