rtk-ai/rtk · error

consent requires interactive terminal — cannot enable teleme

Error message

consent requires interactive terminal — cannot enable telemetry in piped mode

What it means

`rtk telemetry enable` must collect explicit y/N consent, so run_enable requires stdin to be a TTY (io::stdin().is_terminal()) and bails otherwise. The guard is deliberate: consent piped from a script, CI job, or agent is not consent the user actually gave, so RTK refuses to enable telemetry non-interactively.

Source

Thrown at src/core/telemetry_cmd.rs:81

    if salt_path.exists() {
        let hash = super::telemetry::generate_device_hash();
        println!("  device hash:   {}...{}", &hash[..8], &hash[56..]);
    } else {
        println!("  device hash:   (no salt file)");
    }

    println!();
    println!("Data controller: RTK AI Labs, contact@rtk-ai.app");
    println!("Details: https://github.com/rtk-ai/rtk/blob/master/docs/TELEMETRY.md");

    Ok(())
}

fn run_enable() -> Result<()> {
    use std::io::{self, BufRead, IsTerminal};

    if !io::stdin().is_terminal() {
        anyhow::bail!(
            "consent requires interactive terminal — cannot enable telemetry in piped mode"
        );
    }

    eprintln!("RTK collects anonymous usage metrics once per day to improve filters.");
    eprintln!();
    eprintln!("  What:    command names (not arguments), token savings, OS, version");
    eprintln!("  Who:     RTK AI Labs, contact@rtk-ai.app");
    eprintln!("  Details: https://github.com/rtk-ai/rtk/blob/master/docs/TELEMETRY.md");
    eprintln!();
    eprint!("Enable anonymous telemetry? [y/N] ");

    let stdin = io::stdin();
    let mut line = String::new();
    stdin
        .lock()
        .read_line(&mut line)
        .context("Failed to read user input")?;

View on GitHub (pinned to d977e1c316)

Solutions

  1. Run `rtk telemetry enable` yourself in an interactive terminal and answer the [y/N] prompt
  2. In automation, treat this failure as the intended consent guard — leave telemetry disabled rather than scripting around it
  3. Inspect state non-interactively instead: `rtk telemetry status` reads/prints without needing a TTY

Example fix

# before (agent/CI shell: stdin is a pipe)
echo y | rtk telemetry enable
# consent requires interactive terminal — cannot enable telemetry in piped mode

# after: user runs it directly in their terminal
rtk telemetry enable   # answers the [y/N] prompt interactively
Defensive patterns

Strategy: validation

Validate before calling

bash:
# only attempt interactive enable when stdin is a real TTY
if [ -t 0 ]; then
  rtk telemetry enable
else
  echo "rtk telemetry enable needs an interactive terminal; run it yourself" >&2
fi

Try / catch

rust:
use std::io::IsTerminal;
if !std::io::stdin().is_terminal() {
    eprintln!("telemetry consent must be given interactively; skipping");
    return Ok(()); // treat as skip, not failure, in automation
}
telemetry_cmd::run_enable()?;

Prevention

When it happens

Trigger: `echo y | rtk telemetry enable`; `rtk telemetry enable < /dev/null`; running the command inside an agent hook/wrapper where stdin is a pipe, not a terminal; nohup/cron/SSH-without-tty contexts. Anything where is_terminal() returns false.

Common situations: Automation or install scripts trying to pre-accept telemetry; an AI agent running the command on the user's behalf via a bash tool (stdin is a pipe there by definition); CI smoke tests touching telemetry.

Related errors


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