{"record":{"id":"1f78337b2a47f76f","repo":"bazelbuild/bazel","slug":"disallow-values-on-expansion-flags-like-s-is-not","errorCode":null,"errorMessage":"Disallow_Values on expansion flags like %s is not allowed.","messagePattern":"Disallow_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":307,"sourceCode":"    // 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\n  /**\n   * Expand a single policy. If the policy is not about an expansion flag, this will simply return a\n   * list with a single element, oneself. If the policy is for an expansion flag, the policy will\n   * get split into multiple policies applying to each flag the original flag expands to.\n   *\n   * <p>None of the flagPolicies returned should be on expansion flags.","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/com/google/devtools/common/options/InvocationPolicyEnforcer.java#L289-L325","documentation":"Thrown by throwDisallowValuesOnExpansionFlagException when an invocation policy applies a disallow_values operation to an expansion flag. Expansion flags carry no value of their own (they only expand to child flags), so disallowing specific values on them cannot be enforced and is rejected. Note: in the sub-flag propagation path (line ~532) DISALLOW_VALUES on an implicit requirement is silently skipped, but a direct policy on the expansion flag itself throws.","triggerScenarios":"A policy entry with flagName matching an expansion flag and a disallowValues operation present, e.g. {\"flagName\":\"opt\",\"disallowValues\":{\"disallowedValues\":[\"opt\"]}}.","commonSituations":"Trying to forbid a shorthand mode flag (e.g. disallow --opt) in org policy instead of its child flags, policies written against old flag semantics where the flag was not yet an expansion flag.","solutions":["Remove the disallow_values operation on the expansion flag.","Target the child flags the expansion produces (disallow compilation_mode=opt rather than the mode shorthand).","Verify flag expansion behavior in the current Bazel version with bazel help before authoring policy."],"exampleFix":"// before\n{\"flagName\":\"opt\",\"disallowValues\":{\"disallowedValues\":[\"opt\"]}}\n\n// after\n{\"flagName\":\"compilation_mode\",\"disallowValues\":{\"disallowedValues\":[\"opt\"],\"newValue\":[\"fastbuild\"]}}","handlingStrategy":"validation","validationCode":"// Check the flag is not an expansion flag before authoring disallow_values\nif (optionDefinition.hasExpansion() && policyEntry.hasDisallowValues()) {\n  throw new IllegalStateException(\"disallow_values cannot target expansion flag \" + flagName);\n}","typeGuard":null,"tryCatchPattern":"Catch OptionsParsingException from policy enforcement; retarget the disallow_values operation to the child flags the expansion produces.","preventionTips":["Disallow the child flag values instead of the shorthand","Keep a version-pinned map of expansion flags for policy authoring","Smoke-test policies with a trivial bazel command before org-wide rollout"],"tags":["invocation-policy","expansion-flags","policy","bazel"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}