bazelbuild/bazel · error · OptionsParsingException

Illegal use of 'no' prefix on non-boolean option: %s

Error message

Illegal use of 'no' prefix on non-boolean option: %s

What it means

The parser accepts '--no<optionName>' only as the false-spelling of a boolean-syntax option. When stripping 'no' yields a known option but that option does not use boolean value syntax (usesBooleanValueSyntax() is false), the 'no' prefix is illegal and this error is thrown, because non-boolean options require an explicit value.

Source

Thrown at src/main/java/com/google/devtools/common/options/OptionsParserImpl.java:795

      int equalsAt = arg.indexOf('=');
      int nameStartsAt = 2;
      String name =
          equalsAt == -1 ? arg.substring(nameStartsAt) : arg.substring(nameStartsAt, equalsAt);
      if (name.trim().isEmpty()) {
        throw new OptionsParsingException("Invalid options syntax: " + arg, arg);
      }
      unconvertedValue = equalsAt == -1 ? null : arg.substring(equalsAt + 1);
      lookupResult = getWithFallback(OptionsData::getOptionDefinitionFromName, name, fallbackData);

      // Look for a "no"-prefixed option name: "no<optionName>".
      if (lookupResult == null && name.startsWith("no")) {
        name = name.substring(2);
        lookupResult =
            getWithFallback(OptionsData::getOptionDefinitionFromName, name, fallbackData);
        booleanValue = false;
        if (lookupResult != null) {
          if (!lookupResult.definition.usesBooleanValueSyntax()) {
            throw new OptionsParsingException(
                "Illegal use of 'no' prefix on non-boolean option: " + arg, arg);
          }
          if (unconvertedValue != null) {
            throw new OptionsParsingException("Unexpected value after boolean option: " + arg, arg);
          }
          // "no<optionname>" signifies a boolean option w/ false value
          unconvertedValue = "0";
        }
      }
      parsedOptionName = name;
    } else {
      throw new OptionsParsingException("Invalid options syntax: " + arg, arg);
    }

    // Do not recognize internal options, which are treated as if they did not exist.
    if (lookupResult == null || shouldIgnoreOption(lookupResult.definition)) {
      if (isFirstRoundOfParsing) {
        return new ParsedOptionDescriptionOrIgnoredArgs(Optional.empty(), Optional.of(arg));

View on GitHub (pinned to e6e199d060)

Solutions

  1. Check the flag's type with `bazel help <command>` — only boolean-syntax flags support the --no prefix
  2. For value-taking flags, pass an explicit value: --stamp=no or --stamp=false rather than --nostamp
  3. If the flag genuinely starts with 'no' and is non-boolean (legacy naming), pass it with its value as usual — only the stripped-match path triggers this error

Example fix

# before
bazel build --nostamp //...
# after (stamp takes an int/tristate value)
bazel build --stamp=no //...
Defensive patterns

Strategy: validation

Validate before calling

// If you own the option surface, expose boolean-ness so callers can pre-validate
static boolean supportsNoPrefix(OptionDefinition d) {
  return d.usesBooleanValueSyntax();
}
// Callers: only emit "--no" + name when supportsNoPrefix(def) is true.

Prevention

When it happens

Trigger: Passing '--no' + the name of a non-boolean option, e.g. `--nostamp` when stamp takes a value, or `--nocompilation_mode` where the option expects an enum/string argument.

Common situations: Assuming every Bazel flag has a --no variant; carrying over muscle memory from flags like --noincremental_external_repository or --nobuild_python_zip; a real flag name that legitimately starts with 'no' being typed correctly but shadowed by this rule.

Related errors


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