rtk-ai/rtk · error · anyhow::Error

--codex cannot be combined with --no-patch

Error message

--codex cannot be combined with --no-patch

What it means

Symmetric to --auto-patch: `rtk init --codex` skips the patch machinery entirely, so PatchMode::Skip (--no-patch) is meaningless inside codex mode, and the validation at src/hooks/init.rs:292 rejects the combination up front rather than accept a no-op flag.

Source

Thrown at src/hooks/init.rs:292

    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");
        }

        if install_cursor && !global {
            anyhow::bail!("Cursor hooks are global-only. Use: rtk init -g --agent cursor");
        }

        if install_windsurf && !global {
            anyhow::bail!("Windsurf support is global-only. Use: rtk init -g --agent windsurf");
        }

        if install_windsurf {
            run_windsurf_mode(ctx)?;

View on GitHub (pinned to d977e1c316)

Solutions

  1. Run `rtk init --codex` alone — patching never runs in codex mode, so --no-patch adds nothing
  2. Use `rtk init --no-patch` in a separate run for the Claude Code path if needed
  3. Keep one mode's flags per invocation when scripting setup

Example fix

# before
rtk init --codex --no-patch
# --codex cannot be combined with --no-patch

# after
rtk init --codex
rtk init --no-patch      # separate run for the non-codex path
Defensive patterns

Strategy: validation

Validate before calling

bash:
if [[ "$*" == *--codex* && "$*" == *--no-patch* ]]; then
  echo "--codex and --no-patch are mutually exclusive" >&2
  exit 2
fi
rtk init "$@"

Type guard

rust:
enum PatchMode { Ask, Auto, Skip }
fn codex_no_patch_conflict(codex: bool, pm: PatchMode) -> bool {
    codex && matches!(pm, PatchMode::Skip)
}

Try / catch

rust:
// clap-level: #[arg(long, conflicts_with = "no_patch")] codex: bool,
if let Err(e) = init::run(...) {
    if e.to_string().contains("--codex cannot be combined with --no-patch") { exit(2); }
}

Prevention

When it happens

Trigger: `rtk init --codex --no-patch`. Both flags parse; init's validation matches patch_mode against PatchMode::Skip and bails.

Common situations: Teams whose standard init line includes --no-patch appending --codex for one machine; defensive 'disable patching everywhere' policies colliding with codex mode's exclusivity; copy-paste evolution of setup scripts.

Related errors


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