ErrLookup › Background articles › "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them
"mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them
"Mutually exclusive" and "cannot be combined" errors appear when you pass two command-line flags or options that cannot be used together — like "can't supply both nx and xx", "Raw is not compatible with interactive", or "Only one of --tag, --rev and --branch can be specified". They are client-side or preflight rejections, not runtime faults: the tool checked its arguments before doing any work and refused a contradictory request. This article explains why libraries enforce flag exclusivity, which combinations trigger it across CLIs, SDKs and code generators, and how to fix wrapper scripts and configs that keep producing these errors.
Distilled from 100 documented records across 29 repositories.
Background
This family covers errors raised when a caller supplies two or more options whose meanings contradict each other. The messages vary in phrasing — 'mutually exclusive', 'not compatible with', 'can't supply both', 'cannot be used with', 'contradict each other' — but the mechanism is the same: the option set cannot be satisfied simultaneously, so the program aborts instead of picking a winner silently.
Most of these errors are produced very early, before real work starts. Client libraries like redis-rb raise ArgumentError for JSON.SET's nx/xx pair and GEOADD's NX/XX flags before anything reaches the server, mirroring a server that would reject the command anyway. CLI tools like Kamal ('Raw is not compatible with interactive'), Mastra's create command, Archon's workflow preflight, and whenever's crontab action check ('Can only update, write or clear. Choose one.') all validate their option objects at command dispatch and raise before connecting to hosts or touching the filesystem. Some validate even earlier: Phabricator raises PhutilArgumentUsageException during argument parsing, and Cilium's Hubble redaction check surfaces at agent startup when the config cell is instantiated.
The reasons for exclusivity are consistent across the family. Some flags select opposite modes of the same choice: whenever's update/write/clear crontab actions, Redis JSON's nx (only when absent) vs xx (only when present), oh-my-posh's --data-only (forbid probing) vs --data-derive (force probing), Bundler's --major/--minor/--patch update levels. Others select different mechanisms for the same output: openapi-generator's returnResponse vs returnJBossResponse, or its Swagger v2/v3/MicroProfile annotation flags, where templates can emit only one style. A third pattern is structural: a single downstream artifact can only encode one choice, as with Tauri's npm repo#ref spec accepting exactly one git ref, or Deno's dcore accepting one inspector flag per invocation.
A recurring trap is that the conflicting flags often come from different sources rather than a single typed command: a wrapper script with hardcoded flags plus env vars adding more (whenever, CodeWhale, grok-build), option hashes merged from defaults and user input (redis-rb), or config keys resurrected during migrations (openapi-generator's response-style flags). Some tools guard against the combination even when the normal flow makes it nearly unreachable — openapi-generator force-disables useSwaggerAnnotations when v3 is requested, so that guard mainly protects programmatic setter sequences. Notably, a few checks fire only after partial work: Hadoop's createEncryptionZone creates the zone before checking PROVISION_TRASH vs NO_TRASH, so the caller must clean up a half-configured zone — most other tools in this family fail fast with no side effects.
Common causes
- Flags accumulated from multiple sources. Wrapper scripts, aliases, env vars, or CI templates each contribute flags, and the concatenation crosses an exclusive pair — e.g. a hardcoded -i plus an env var adding --clear-crontab to whenever, or an alias that always passes -i combined with a manual --raw in Kamal.
- Option hashes merged from defaults and user input. redis-rb's json_set and geoadd fail when kwargs like nx: params[:create], xx: params[:update] both end up truthy after merging an unfiltered params hash or a defaults overlay.
- Configuration migration leaving both old and new flags. openapi-generator errors when a config that already set returnResponse gains returnJBossResponse during a Quarkus migration, or when merged config sources (CLI + --config + configOptions) both set Swagger v2 and v3 annotation flags.
- Hidden config making an explicit flag collide. bundle update --major fails even though only one flag was passed, because BUNDLE_PREFER_PATCH/prefer_patch implicitly appends :patch to Bundler's patch-level list, making two entries.
- Genuinely misunderstanding two modes as combinable. Some pairs look additive but aren't: Phabricator's --active/--archived (a task lives in exactly one table), Phabricator's reparse --importing vs specific step flags, or Archon's --base with --no-worktree where the flag would be silently ignored.
- Contradictory semantics the tool refuses to arbitrate. Passing allowlist and denylist together (Cilium's Hubble header redaction), oh-my-posh's --data-only with --data-derive, or Beads' multiple text sources (--stdin with --file and positional text) where only one input can apply.
What usually fixes it
- Model exclusive choices as a single value, not independent booleans: one ACTION variable for whenever, one mode symbol (:nx/:xx/nil) for redis-rb, one enum (active|archived|both) for Phabricator wrappers, or a single responseStyle/swaggerVersion input for openapi-generator wrappers.
- Read the error literally — most messages name the exact conflicting flags, so remove or unset all but one of them rather than guessing.
- Audit the full effective configuration before retrying: check merged option maps, bundle config get prefer_patch, Helm values/ConfigMap merges, and stored CI pipelines for resurrected flags.
- Keep the two legitimate modes in separate branches in wrapper scripts (one mode per invocation) instead of building one mega-command that concatenates flags from multiple sources.
- When a flag pair must be swapped during a migration, do the swap atomically in the same commit or config change so the old and new flags never coexist.
- For tools that fail after partial work (Hadoop's encryption zone), validate the flag set before the call and have a recovery plan: provision trash manually or delete and recreate.
Documented occurrences
- [fail] Can only update, write or clear. Choose one. (javan/whenever)
- You cannot combine [returnResponse] and [returnJBossResponse] since they are mutually exclusive (OpenAPITools/openapi-generator)
- can not have both PROVISION_TRASH and NO_TRASH flags (apache/hadoop)
- Flags 'useSwaggerAnnotations' (v2) and 'useSwaggerV3Annotations' (v3) are mutually exclusive. Please enable only one. (OpenAPITools/openapi-generator)
- You can not specify both "--active" and "--archived" tasks: no tasks can match both constraints. (phacility/phabricator)
- Flags 'useSwaggerV3Annotations' and 'useMicroProfileOpenAPIAnnotations' are mutually exclusive. Please enable only one. (OpenAPITools/openapi-generator)
- nx and xx are mutually exclusive (redis/redis-rb)
- Raw is not compatible with interactive (basecamp/kamal)
- Detach is not compatible with #{incompatible_options.join(" or ")} (basecamp/kamal)
- Only one of --hubble-redact-http-headers-allow and --hubble-redact-http-headers-deny can be specified, not both (cilium/cilium)
- Provide only one of the following options: #{patch_level.join(", ")} (ruby/ruby)
- {} (xai-org/grok-build)
- --codex cannot be combined with --opencode (rtk-ai/rtk)
- cannot combine %s (gastownhall/beads)
- Raw is not compatible with interactive (basecamp/kamal)
- Choosing steps with "--importing" conflicts with flags which select specific steps. (phacility/phabricator)
- `codewhale --continue` resumes the interactive TUI. Use `codewhale exec --continue <PROMPT>` to continue a session non-interactively. (Hmbown/CodeWhale)
- --base has no effect with --no-worktree. Remove --base or drop --no-worktree. (coleam00/Archon)
- The --llm option can only be used with the default template (mastra-ai/mastra)
- Raw is not compatible with #{incompatible_options.join(" or ")} (basecamp/kamal)
…and 80 more across the corpus — use search.
Honest provenance: generated on 2026-09-01 from AI-assisted analysis of the linked records. See how records are made.