rtk-ai/rtk · error

proxy requires a command to execute Usage: rtk proxy <comman

Error message

proxy requires a command to execute
Usage: rtk proxy <command> [args...]

What it means

rtk proxy executes a command verbatim (no filtering) while tracking metrics, so it needs at least one command token; empty args bail with an embedded usage line. Note that a single quoted argument containing spaces is shell-split by rtk ('rtk proxy 'head -50 file.php'' becomes head -50 file.php), so a one-arg call is valid as long as the arg is non-empty.

Source

Thrown at src/main.rs:2521

                let shell = if cfg!(windows) { "cmd" } else { "sh" };
                let flag = if cfg!(windows) { "/C" } else { "-c" };
                let status = ProcCommand::new(shell)
                    .arg(flag)
                    .arg(&raw)
                    .status()
                    .with_context(|| format!("Failed to execute: {}", raw))?;
                core::utils::exit_code_from_status(&status, "run")
            }
        }

        Commands::Proxy { args } => {
            use std::io::{Read, Write};
            use std::process::Stdio;
            use std::sync::atomic::{AtomicU32, Ordering};
            use std::thread;

            if args.is_empty() {
                anyhow::bail!(
                    "proxy requires a command to execute\nUsage: rtk proxy <command> [args...]"
                );
            }

            let timer = core::tracking::TimedExecution::start();

            // If a single quoted arg contains spaces, split it respecting quotes (#388).
            // e.g. rtk proxy 'head -50 file.php' → cmd=head, args=["-50", "file.php"]
            // e.g. rtk proxy 'git log --format="%H %s"' → cmd=git, args=["log", "--format=%H %s"]
            let (cmd_name, cmd_args): (String, Vec<String>) = if args.len() == 1 {
                let full = args[0].to_string_lossy();
                let parts = shell_split(&full);
                if parts.len() > 1 {
                    (parts[0].clone(), parts[1..].to_vec())
                } else {
                    (full.into_owned(), vec![])
                }
            } else {

View on GitHub (pinned to d977e1c316)

Solutions

  1. Run `rtk proxy <command> [args...]`, e.g. `rtk proxy git log --oneline -20`
  2. Quote a whole command as one arg only when you want rtk's built-in split: `rtk proxy 'git log --format="%H %s"'`
  3. Add an argument guard in wrappers before calling rtk

Example fix

# before
rtk proxy                 # bails with usage

# after
rtk proxy git log --oneline -20
Defensive patterns

Strategy: validation

Validate before calling

# bash: guard before proxying to rtk proxy
[ $# -ge 1 ] && [ -n "$1" ] || { echo 'usage: rtk proxy <command> [args...]' >&2; exit 2; }
rtk proxy "$@"

Prevention

When it happens

Trigger: `rtk proxy` with no arguments, or a wrapper passing an empty string that shell_split reduces to nothing (src/main.rs:2525).

Common situations: Scripts assembling `rtk proxy $CMD` from optional variables; argument-dropping in nested quoting layers.

Related errors


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