{"record":{"id":"12825da85a174a97","repo":"bazelbuild/bazel","slug":"allow-values-on-expansion-flags-like-s-is-not-all","errorCode":null,"errorMessage":"Allow_Values on expansion flags like %s is not allowed.","messagePattern":"Allow_Values on expansion flags like (.+?) is not allowed\\.","errorType":"exception","errorClass":"OptionsParsingException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/google/devtools/common/options/InvocationPolicyEnforcer.java","lineNumber":301,"sourceCode":"      FlagPolicyWithContext policyWithContext =\n          new FlagPolicyWithContext(policy, optionDescription, origin);\n      List<FlagPolicyWithContext> policies = expandPolicy(policyWithContext, parser, loglevel);\n      expandedPolicies.addAll(policies);\n    }\n\n    // Only keep that last policy for each flag.\n    ImmutableMap.Builder<String, FlagPolicyWithContext> effectivePolicy = ImmutableMap.builder();\n    for (FlagPolicyWithContext expandedPolicy : expandedPolicies) {\n      String flagName = expandedPolicy.policy.getFlagName();\n      effectivePolicy.put(flagName, expandedPolicy);\n    }\n\n    return effectivePolicy.buildKeepingLast().values().asList();\n  }\n\n  private static void throwAllowValuesOnExpansionFlagException(String flagName)\n      throws OptionsParsingException {\n    throw new OptionsParsingException(\n        String.format(\"Allow_Values on expansion flags like %s is not allowed.\", flagName));\n  }\n\n  private static void throwDisallowValuesOnExpansionFlagException(String flagName)\n      throws OptionsParsingException {\n    throw new OptionsParsingException(\n        String.format(\"Disallow_Values on expansion flags like %s is not allowed.\", flagName));\n  }\n\n  private static OptionsParsingException throwUndefinedBehaviorException(FlagPolicy policy)\n      throws OptionsParsingException {\n    throw new OptionsParsingException(\n        String.format(\n            \"SetValue operation from invocation policy for has an undefined behavior: %s\",\n            policy\n            ));\n  }\n","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/com/google/devtools/common/options/InvocationPolicyEnforcer.java#L283-L319","documentation":"Thrown by throwAllowValuesOnExpansionFlagException when an invocation policy applies an allow_values operation to an expansion flag (a flag whose only job is to expand into other flags, like --fastbuild or --opt-style shorthand flags). Constraining values on an expansion flag is meaningless/impossible to enforce, so it is rejected outright.","triggerScenarios":"A policy entry with flagName equal to a known expansion flag and an allowValues operation set. Detected during policy expansion (expandPolicy) where the enforcer checks isExpansion before splitting policies onto child flags.","commonSituations":"Policy authors targeting shorthand flags (--fastbuild) instead of the real flags they expand to, policies written before a flag became an expansion flag (flag semantics changed across Bazel versions), auto-generated policies from flag inventories.","solutions":["Remove the allow_values operation on the expansion flag.","Apply allow_values to the concrete child flags the expansion expands into (e.g. compilation_mode instead of a mode shorthand).","Run bazel help to confirm which flags are expansion flags in your version before writing policy.","Keep policies version-pinned to the Bazel release they were written for."],"exampleFix":"// before\n{\"flagName\":\"fastbuild\",\"allowValues\":{\"allowedValues\":[\"fastbuild\"]}}\n\n// after\n{\"flagName\":\"compilation_mode\",\"allowValues\":{\"allowedValues\":[\"fastbuild\",\"dbg\"]}}","handlingStrategy":"validation","validationCode":"// Check the flag is not an expansion flag before authoring allow_values\n// (isExpansion is determined from the option definition in the running binary)\nif (optionDefinition.hasExpansion() && policyEntry.hasAllowValues()) {\n  throw new IllegalStateException(\"allow_values cannot target expansion flag \" + flagName);\n}","typeGuard":null,"tryCatchPattern":"Catch OptionsParsingException from policy enforcement; the message names the expansion flag — retarget the operation to its child flags.","preventionTips":["Check bazel help to confirm a flag is not an expansion flag before constraining it","Target concrete child flags (compilation_mode) rather than mode shorthands","Re-validate policies on Bazel upgrades since flags can become expansion flags"],"tags":["invocation-policy","expansion-flags","policy","bazel"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}