emilk/egui · error

Failed to read {}: {}

Error message

Failed to read {}: {}

What it means

This panic occurs in HarnessBuilder::load_config when the kittest config file (kittest.toml) exists but cannot be read from disk. The library wraps the std::fs::read_to_string result and panics on any I/O error rather than falling back to defaults, because a config that exists but is unreadable signals an environment problem the user must fix. It is distinct from a parse failure (which produces 'Failed to parse ...').

Source

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

                "`{prefix}failed_pixel_count_threshold` in kittest.toml is deprecated; \
                 use `{prefix}max_failed_pixels` instead."
            );
        }
    }
}

fn load_config() -> Config {
    if let Ok(config_path) = find_kittest_toml() {
        match std::fs::read_to_string(&config_path) {
            Ok(config_str) => {
                warn_about_deprecated_keys(&config_str);
                match toml::from_str(&config_str) {
                    Ok(config) => config,
                    Err(err) => panic!("Failed to parse {}: {err}", config_path.display()),
                }
            }
            Err(err) => {
                panic!("Failed to read {}: {}", config_path.display(), err);
            }
        }
    } else {
        Config::default()
    }
}

/// Get the global configuration.
///
/// See [`Config::global`] for details.
pub fn config() -> &'static Config {
    Config::global()
}

impl Config {
    /// Get or load the global configuration.
    ///
    /// This is either

View on GitHub (pinned to 441971a776)

Solutions

  1. Check file permissions on the config file and fix them (chmod/chown) so the test user can read it
  2. Verify the config path is a regular file, not a directory or broken symlink
  3. Remove or rename the config file if you intended to use defaults instead
  4. Re-run the test to confirm the I/O error is gone

Example fix

// before (shell)
$ ls -l kittest.toml
-rw------- 1 root root kittest.toml
// after
$ sudo chmod 644 kittest.toml
Defensive patterns

Strategy: validation

Validate before calling

let path = std::path::Path::new("kittest.toml");
assert!(path.is_file(), "kittest.toml must be a readable regular file");
assert!(!path.metadata().map(|m| m.permissions().readonly()).unwrap_or(true) || cfg!(unix), "check read permissions");

Try / catch

// load_config panics; ensure the file is readable before running tests
match std::fs::File::open("kittest.toml") {
    Ok(_) => run_kittest_tests(),
    Err(e) => eprintln!("config unreadable, fix before testing: {e}"),
}

Prevention

When it happens

Trigger: Calling the harness builder when a kittest config file exists at the resolved config path but fs::read_to_string returns Err — e.g. missing read permissions, the path is a directory, or the file is deleted between existence check and read.

Common situations: CI containers running tests as a non-root user without file permissions; a kittest.toml checked in with restrictive modes; kittest.toml accidentally replaced by a directory or symlink to an inaccessible file; disk/permission issues in sandboxed environments.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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