rtk-ai/rtk · error
tree command not found. Install it first: - macOS: brew inst
Error message
tree command not found. Install it first: - macOS: brew install tree - Ubuntu/Debian: sudo apt install tree - Fedora/RHEL: sudo dnf install tree - Arch: sudo pacman -S tree
What it means
rtk tree does not reimplement tree in Rust — it shells out to the external `tree` binary via resolved_command("tree") and first checks tool_exists("tree"). If no tree is on PATH it bails with per-distro install instructions before touching anything else.
Source
Thrown at src/cmds/system/tree.rs:16
//! tree command - proxy to native tree with token-optimized output
//!
//! This module proxies to the native `tree` command and filters the output
//! to reduce token usage while preserving structure visibility.
//!
//! Token optimization: automatically excludes noise directories via -I pattern
//! unless -a flag is present (respecting user intent).
use super::constants::NOISE_DIRS;
use crate::core::runner::{self, RunOptions};
use crate::core::utils::{resolved_command, tool_exists};
use anyhow::Result;
pub fn run(args: &[String], verbose: u8) -> Result<i32> {
if !tool_exists("tree") {
anyhow::bail!(
"tree command not found. Install it first:\n\
- macOS: brew install tree\n\
- Ubuntu/Debian: sudo apt install tree\n\
- Fedora/RHEL: sudo dnf install tree\n\
- Arch: sudo pacman -S tree"
);
}
let mut cmd = resolved_command("tree");
let show_all = args.iter().any(|a| a == "-a" || a == "--all");
let has_ignore = args.iter().any(|a| a == "-I" || a.starts_with("--ignore="));
if !show_all && !has_ignore {
let ignore_pattern = NOISE_DIRS.join("|");
cmd.arg("-I").arg(&ignore_pattern);
}
View on GitHub (pinned to d977e1c316)
Solutions
- Install tree: `brew install tree` (macOS), `sudo apt install tree` (Debian/Ubuntu), `sudo dnf install tree` (Fedora/RHEL), `sudo pacman -S tree` (Arch)
- In containers, bake it into the image: `RUN apt-get update && apt-get install -y --no-install-recommends tree`
- Without tree, approximate the overview: `rtk proxy fd --type d` or `rtk proxy ls -R | head -100`
Example fix
# before rtk tree # tree command not found. Install it first: ... # after (Ubuntu/Debian) sudo apt install tree && rtk tree # Dockerfile RUN apt-get update && apt-get install -y --no-install-recommends tree
Defensive patterns
Strategy: validation
Validate before calling
bash: if ! command -v tree >/dev/null 2>&1; then echo "tree missing — falling back to fd directory view" >&2 exec rtk proxy fd --type d --max-depth 3 fi rtk tree "$@"
Type guard
rust:
fn tree_available() -> bool {
which::which("tree").is_ok()
} Try / catch
rust:
match tree_cmd::run(&args, verbose) {
Err(e) if e.to_string().contains("tree command not found") => {
let st = std::process::Command::new("ls").arg("-R").status()?;
std::process::exit(st.code().unwrap_or(1));
}
r => r?,
} Prevention
- Add tree to container images: apt-get install -y --no-install-recommends tree
- Check `command -v tree` in scripts that call rtk tree on shared machines
- Keep an fd/ls fallback for environments you don't control
- Remember hooks rewrite bare `tree` to `rtk tree` — the failure can appear far from your own command
When it happens
Trigger: `rtk tree` (or hook-rewritten `tree`) where tree is not installed: slim Docker images (node:slim, alpine, distroless), minimal CI runners, fresh macOS without brew, or a Nix/devshell that omits the package.
Common situations: Containerized dev/CI environments; ephemeral CI agents; hook-rewritten shells where plain `tree` from an agent silently becomes `rtk tree` and fails; portable dotfiles moved to a new machine.
AI-assisted analysis of rtk-ai/rtk@d977e1c316 (2026-08-16).
Data as JSON: /api/errors/09ceedc39cba670d.
Report an issue: GitHub.