rtk-ai/rtk · error

--codex cannot be combined with --opencode

Error message

--codex cannot be combined with --opencode

What it means

`rtk init --codex` is a self-contained mode that ONLY installs Codex integration (it calls run_codex_mode). The validation block at src/hooks/init.rs:280 rejects every flag that would select a different integration; combining --codex with --opencode is contradictory (two different agent targets), so it bails before any installation happens.

Source

Thrown at src/hooks/init.rs:280

#[allow(clippy::too_many_arguments)]
pub fn run(
    global: bool,
    install_claude: bool,
    install_opencode: bool,
    install_cursor: bool,
    install_windsurf: bool,
    install_cline: bool,
    claude_md: bool,
    hook_only: bool,
    codex: bool,
    patch_mode: PatchMode,
    ctx: InitContext,
) -> Result<()> {
    let InitContext { dry_run, .. } = ctx;
    // Validation: Codex mode conflicts
    if codex {
        if install_opencode {
            anyhow::bail!("--codex cannot be combined with --opencode");
        }
        if claude_md {
            anyhow::bail!("--codex cannot be combined with --claude-md");
        }
        if hook_only {
            anyhow::bail!("--codex cannot be combined with --hook-only");
        }
        if matches!(patch_mode, PatchMode::Auto) {
            anyhow::bail!("--codex cannot be combined with --auto-patch");
        }
        if matches!(patch_mode, PatchMode::Skip) {
            anyhow::bail!("--codex cannot be combined with --no-patch");
        }
        run_codex_mode(global, ctx)?;
    } else {
        // Validation: Global-only features
        if install_opencode && !global {
            anyhow::bail!("OpenCode plugin is global-only. Use: rtk init -g --opencode");

View on GitHub (pinned to d977e1c316)

Solutions

  1. Run codex mode alone: `rtk init --codex`
  2. If you also want OpenCode support, run a second separate command: `rtk init -g --opencode`
  3. Drop --codex if OpenCode is what you actually wanted

Example fix

# before
rtk init --codex --opencode
# --codex cannot be combined with --opencode

# after: two separate installs
rtk init --codex
code  # then set up opencode separately:
rtk init -g --opencode
Defensive patterns

Strategy: validation

Validate before calling

bash:
# --codex is exclusive: never pass another integration flag with it
if [[ "$*" == *--codex* && "$*" == *--opencode* ]]; then
  echo "--codex and --opencode are mutually exclusive; run them separately" >&2
  exit 2
fi
rtk init "$@"

Type guard

rust:
struct InitFlags { codex: bool, opencode: bool, claude_md: bool, hook_only: bool }
fn codex_conflicts(f: &InitFlags) -> bool {
    f.codex && (f.opencode || f.claude_md || f.hook_only)
}

Try / catch

rust (better: let clap reject it before runtime):
// in the clap derive for the init subcommand:
#[arg(long, conflicts_with_all = ["opencode", "claude_md", "hook_only"])]
codex: bool,
// runtime catch otherwise:
if let Err(e) = init::run(...) { if e.to_string().starts_with("--codex cannot") { exit(2); } }

Prevention

When it happens

Trigger: `rtk init --codex --opencode` — the clap flags parse fine individually, but the pair reaches init's validation and bails with the exact conflict named. Common when a script concatenates option lists from two setup guides.

Common situations: Copy-pasting flags from different README sections (one for Codex, one for OpenCode); scripted bootstrap that accumulates options; misreading --codex as an additive integration rather than an exclusive mode.

Related errors


AI-assisted analysis of rtk-ai/rtk@d977e1c316 (2026-08-16). Data as JSON: /api/errors/2ef9aeff235d42a7. Report an issue: GitHub.