denisidoro/navi · error · anyhow

`{}` not found in cheatsh. Output: {}

Error message

`{}` not found in cheatsh.
Output:
{}

What it means

After wget successfully fetches the cheat.sh page, `cheatsh::call` checks whether the queried topic exists. If the response doesn't contain the expected query (cheat.sh returns its 'unknown topic' page), navi returns an anyhow error embedding the query and the raw markdown output so the user can see what cheat.sh actually returned.

Source

Thrown at src/clients/cheatsh.rs:51

        }
    };

    let out = child.wait_with_output().context("Failed to wait for wget")?;

    if let Some(0) = out.status.code() {
        let stdout = out.stdout;
        let plain_bytes = strip_ansi_escapes::strip(stdout);

        let markdown = String::from_utf8(plain_bytes).context("Output is invalid utf8")?;
        if markdown.starts_with("Unknown topic.") {
            let msg = format!(
                "`{}` not found in cheatsh.
Output:
{}
",
                &query, markdown,
            );
            return Err(anyhow!(msg));
        }

        let lines = as_lines(query, &markdown);
        Ok(lines)
    } else {
        let msg = format!(
            "Failed to call:
wget {}

Output:
{}

Error:
{}
",
            args.join(" "),
            String::from_utf8(out.stdout).unwrap_or_else(|_e| "Unable to get output message".to_string()),
            String::from_utf8(out.stderr).unwrap_or_else(|_e| "Unable to get error message".to_string())

View on GitHub (pinned to f7330b9ad5)

Solutions

  1. Check the spelling of the query/topic and search cheat.sh directly in a browser (`https://cheat.sh/<topic>`)
  2. Use a topic that exists on cheat.sh or use a local cheatsheet directory instead
  3. Inspect the Output section of the error to see what cheat.sh returned and adjust the query accordingly
  4. If cheat.sh format changed, update navi to a newer version with fixed parsing

Example fix

// before
$ navi cheatsh pyhton lists
`pyhton lists` not found in cheatsh.
// after
$ navi cheatsh python lists
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the topic exists before calling
fn topic_exists_on_cheatsh(topic: &str) -> bool {
    std::process::Command::new("wget").arg("-q").arg("--spider")
        .arg(format!("https://cheat.sh/{}", topic))
        .status().map(|s| s.success()).unwrap_or(false)
}

Try / catch

match cheatsh::call(query, opts) {
    Ok(lines) => render(lines),
    Err(e) if e.to_string().contains("not found in cheatsh") => {
        eprintln!("topic '{}' does not exist on cheat.sh; check spelling", query);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `call(query)` where the downloaded markdown does not match the query: the topic doesn't exist on cheat.sh, the query is misspelled, or cheatsheet lookup uses a name cheat.sh doesn't know.

Common situations: Typos in the cheatsheet/topic name, querying a language/tool that cheat.sh doesn't cover, using a language code prefix incorrectly, or cheat.sh changing its response format so detection of 'not found' misfires.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of denisidoro/navi@f7330b9ad5 (2026-09-03). Data as JSON: /api/errors/8fce75dde2632e7f. Report an issue: GitHub.