emilk/egui · error · io::Error

NotFound

NotFound

Error message

kittest.toml not found

What it means

`find_kittest_toml` walks up the directory tree from the current directory looking for a `kittest.toml` config file; if it reaches the filesystem root without finding one, it returns an `io::Error` with `ErrorKind::NotFound`. Kittest requires this file (even if minimal) to load snapshot/tolerance configuration.

Source

Thrown at crates/egui_kittest/src/config.rs:80

    /// Override the maximum number of failing pixels for this OS.
    #[serde(alias = "failed_pixel_count_threshold")]
    max_failed_pixels: Option<usize>,
}

fn find_kittest_toml() -> io::Result<std::path::PathBuf> {
    let mut current_dir = std::env::current_dir()?;

    loop {
        let current_kittest = current_dir.join("kittest.toml");
        // Check if Cargo.toml exists in this directory
        if current_kittest.exists() {
            return Ok(current_kittest);
        }

        // Move up one directory
        if !current_dir.pop() {
            return Err(io::Error::new(
                io::ErrorKind::NotFound,
                "kittest.toml not found",
            ));
        }
    }
}

/// The old name of `max_failed_pixels` is still accepted, but warned about.
fn warn_about_deprecated_keys(config_str: &str) {
    let Ok(config) = toml::from_str::<toml::Table>(config_str) else {
        return;
    };

    let mut sections = vec![("", &config)];
    for name in ["windows", "mac", "linux"] {
        if let Some(table) = config.get(name).and_then(toml::Value::as_table) {
            sections.push((name, table));
        }

View on GitHub (pinned to 441971a776)

Solutions

  1. Create a `kittest.toml` in the directory you run tests from (or the crate root) with at least an empty config.
  2. Run tests with the crate directory as working directory (e.g. `cargo test -p mycrate` from that directory, or set `current_dir` in CI).
  3. In CI, add a step to `cd` into the crate root before running the test binary.
  4. Copy the `kittest.toml` from a sibling crate or the kittest docs as a starting template.

Example fix

// before (CI run from repo root, no config found)
- run: cargo test --all
// after
- run: cd crates/my_crate && cargo test
// and add crates/my_crate/kittest.toml with e.g.:
// snapshot_path = "snapshots"
Defensive patterns

Strategy: validation

Validate before calling

// Check the search path before loading
if !std::path::Path::new("kittest.toml").exists() {
    eprintln!("kittest.toml missing from current dir; run from crate root");
}

Try / catch

match Config::load() {
    Ok(cfg) => cfg,
    Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
        eprintln!("kittest.toml not found — running from crate root? using defaults");
        Config::default()
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Running tests with `load_config` from a working directory that is not inside (or below) a directory containing `kittest.toml` — e.g. running a single test binary from `target/debug/deps`, running from the repo root when the file only exists in a crate subdirectory, or simply never having created the file.

Common situations: CI invoking tests with a different CWD than local runs; monorepo where the config lives in `crates/foo/` but tests run from `/`; fresh clone missing the dotfile-style config; Docker containers running the test binary from `/`.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of emilk/egui@441971a776 (2026-09-12). Data as JSON: /api/errors/8c6e33a885372ee8. Report an issue: GitHub.