a-b-street/abstreet · error

Couldn't read

Error message

Couldn't read {}

What it means

The default Settings::read_svg closure panics when the SVG file at the given path cannot be opened (fs_err::File::open fails). It reports "Couldn't read {path}" — typically the file doesn't exist or isn't readable at the time an asset is loaded.

Solutions

  1. Verify the path exists relative to the process's current working directory.
  2. Fix the asset path/filename spelling and case.
  3. Ship the asset with the application and reference it correctly in packaging.
  4. Override Settings.read_svg with include_bytes!-based embedding or a custom loader returning empty bytes/own error handling.

Example fix

// before
let mut file = fs_err::File::open(path).unwrap_or_else(|_| panic!("Couldn't read {}", path));
// after
let mut file = fs_err::File::open(path).unwrap_or_else(|e| panic!("Couldn't read {}: {}", path, e));
Defensive patterns

Strategy: validation

Validate before calling

if !std::path::Path::new(path).exists() { eprintln!("missing asset: {}", path); }
// or at startup, probe all assets:
// for p in REQUIRED_SVGS { assert!(Path::new(p).exists(), "missing asset {}", p); }

Try / catch

// Provide a custom read_svg that returns empty bytes + logs instead of panicking:
settings.read_svg = Box::new(|path| std::fs::read(path).unwrap_or_else(|e| { log::error!("{}: {}", path, e); Vec::new() }));

Prevention

When it happens

Trigger: Calling load_svg with a path that doesn't exist on disk, a path relative to the wrong working directory, or a file without read permissions, while using the default read_svg implementation in Settings.

Common situations: Assets not packaged with the binary (missing from include dir or install bundle), running the app from a different cwd than during development, typos in asset filenames, Linux case-sensitivity vs Windows-authored paths.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/5734d64e4f84793e. Report an issue: GitHub.

Appendix: source

Thrown at widgetry/src/runner.rs:227

    /// Specify the title of the window to open.
    pub fn new(window_title: &str) -> Settings {
        Settings {
            window_title: window_title.to_string(),
            #[cfg(target_arch = "wasm32")]
            root_dom_element_id: "widgetry-canvas".to_string(),
            assets_base_url: None,
            assets_are_gzipped: false,
            dump_raw_events: false,
            scale_factor: None,
            require_minimum_width: None,
            window_icon: None,
            loading_tips: None,
            load_default_textures: true,
            read_svg: Box::new(|path| {
                use std::io::Read;

                let mut file =
                    fs_err::File::open(path).unwrap_or_else(|_| panic!("Couldn't read {}", path));
                let mut buffer = Vec::new();
                file.read_to_end(&mut buffer)
                    .unwrap_or_else(|_| panic!("Couldn't read all of {}", path));
                buffer
            }),
            canvas_settings: CanvasSettings::new(),
        }
    }

    /// Log every raw winit event to the DEBUG level.
    pub fn dump_raw_events(mut self) -> Self {
        assert!(!self.dump_raw_events);
        self.dump_raw_events = true;
        self
    }

    /// Override the initial HiDPI scale factor from whatever winit initially detects.
    pub fn scale_factor(mut self, scale_factor: f64) -> Self {

View on GitHub (pinned to 0964f29315)