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

Cursor hooks are global-only. Use: rtk init -g --agent curso

Error message

Cursor hooks are global-only. Use: rtk init -g --agent cursor

What it means

Cursor hooks are installed at the user level (global Cursor settings), not per-project, so rtk init requires the global flag. The validation at src/hooks/init.rs:302 bails when install_cursor is set and global is false, embedding the corrective command `rtk init -g --agent cursor` in the message.

Source

Thrown at src/hooks/init.rs:302

        }
        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)?;
        } else if install_cline {
            run_cline_mode(ctx)?;
        } else {
            // Mode selection (Claude Code / OpenCode)
            match (install_claude, install_opencode, claude_md, hook_only) {
                (false, true, _, _) => run_opencode_only_mode(ctx)?,
                (true, opencode, true, _) => run_claude_md_mode(global, opencode, ctx)?,
                (true, opencode, false, true) => {
                    run_hook_only_mode(global, patch_mode, opencode, ctx)?
                }

View on GitHub (pinned to d977e1c316)

Solutions

  1. Run `rtk init -g --agent cursor` as the error instructs
  2. For project-local setup, use the default: `rtk init` (Claude Code mode writes into the project)
  3. Windsurf has the same rule (`rtk init -g --agent windsurf`) — batch your global-only setups with one -g run

Example fix

# before
rtk init --agent cursor
# Cursor hooks are global-only. Use: rtk init -g --agent cursor

# after
rtk init -g --agent cursor
# combine other global-only agents in the same global run if needed:
rtk init -g --agent windsurf
Defensive patterns

Strategy: validation

Validate before calling

bash:
# Cursor hooks install user-level: require -g up front
if [[ "$*" == *--agent\ cursor* && "$*" != *-g* && "$*" != *--global* ]]; then
  echo "Cursor hooks are global-only — rerunning with -g" >&2
  set -- -g "$@"
fi
rtk init "$@"

Type guard

rust:
fn cursor_invocation_valid(cursor: bool, global: bool) -> bool {
    !cursor || global
}

Try / catch

bash:
rtk init --agent cursor 2>err.txt || {
  grep -q 'global-only' err.txt && exec rtk init -g --agent cursor
}

Prevention

When it happens

Trigger: `rtk init --agent cursor` without -g/--global — typically run inside a project directory right after cloning, expecting a repo-local hook install like the default Claude Code mode.

Common situations: New-machine setup following Cursor docs while cd'd into a repo; porting a project-local init script to Cursor by only swapping the agent flag; assuming symmetry between local Claude Code hooks and Cursor hooks.

Related errors


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