{"record":{"id":"9ec18b23e91dda3e","repo":"bazelbuild/bazel","slug":"must-be-in-the-form-of-a-key-value-value-assig","errorCode":null,"errorMessage":"Must be in the form of a 'key=value[,value]' assignment","messagePattern":"Must be in the form of a 'key=value\\[,value\\]' assignment","errorType":"validation","errorClass":"OptionsParsingException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/google/devtools/common/options/Converters.java","lineNumber":576,"sourceCode":"    private static final Splitter SPLITTER = Splitter.on(',');\n\n    private final Converter<K> keyConverter;\n    private final Converter<V> valueConverter;\n    private final AllowEmptyKeys allowEmptyKeys;\n\n    public AssignmentToListOfValuesConverter(\n        Converter<K> keyConverter, Converter<V> valueConverter, AllowEmptyKeys allowEmptyKeys) {\n      this.keyConverter = keyConverter;\n      this.valueConverter = valueConverter;\n      this.allowEmptyKeys = allowEmptyKeys;\n    }\n\n    @Override\n    public Map.Entry<K, List<V>> convert(String input, @Nullable Object conversionContext)\n        throws OptionsParsingException {\n      int pos = input.indexOf(\"=\");\n      if (allowEmptyKeys == AllowEmptyKeys.NO && pos <= 0) {\n        throw new OptionsParsingException(\n            \"Must be in the form of a 'key=value[,value]' assignment\");\n      }\n\n      String key = pos <= 0 ? \"\" : input.substring(0, pos);\n      List<String> values = SPLITTER.splitToList(input.substring(pos + 1));\n      if (values.contains(\"\")) {\n        // If the list contains exactly the empty string, it means an empty value was passed and we\n        // should instead return an empty list.\n        if (values.size() == 1) {\n          values = ImmutableList.of();\n        } else {\n          throw new OptionsParsingException(\n              \"Variable definitions must not contain empty strings or leading / trailing commas\");\n        }\n      }\n      ImmutableList.Builder<V> convertedValues = ImmutableList.builder();\n      for (String value : values) {\n        convertedValues.add(valueConverter.convert(value, conversionContext));","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/com/google/devtools/common/options/Converters.java#L558-L594","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Supply the full assignment including '=' and at least one value: --flag=key=value or --flag=key=v1,v2.","If an empty key is legitimately required, check whether the flag's converter was built with AllowEmptyKeys.YES and use the correct flag instead.","Validate generated values with a regex like ^.+=(.+,.*)*$ before passing them to the command line."],"exampleFix":"# before\n--test_filter=foo\n\n# after\n--test_filter=foo=bar,baz","handlingStrategy":"validation","validationCode":"// Validate key=value[,value] shape before passing to a map-of-lists flag\nboolean isValidKeyedList(String s) {\n  if (s == null) return false;\n  int pos = s.indexOf(\"=\");\n  return pos > 0; // AllowEmptyKeys.NO requires non-empty key\n}","typeGuard":null,"tryCatchPattern":"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.","preventionTips":["Prefer passing key= (empty value) over bare key when an empty list is intended","Document the exact key=v1,v2 syntax next to every map-of-lists flag in project docs","Regex-check generated values: ^.+=([^,]+,?)*$"],"tags":["options-parsing","converter","command-line","bazel"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}