a-b-street/abstreet · error

Couldn't read all of

Error message

Couldn't read all of {}

What it means

The default Settings::read_svg closure also panics if reading the opened file to the end fails (read_to_end errors). "Couldn't read all of {path}" means the file opened but its full contents could not be read (I/O error mid-read).

Solutions

  1. Retry the read; transient I/O errors often resolve on a second attempt.
  2. Check disk/filesystem health for the volume holding the asset.
  3. Ensure no external process deletes/renames assets while the app starts.
  4. Provide a custom read_svg closure that returns an error result instead of panicking.

Example fix

// before
file.read_to_end(&mut buffer).unwrap_or_else(|_| panic!("Couldn't read all of {}", path));
// after
file.read_to_end(&mut buffer).unwrap_or_else(|e| panic!("Couldn't read all of {}: {}", path, e));
Defensive patterns

Strategy: retry

Validate before calling

// Verify readability before handing the path to widgetry
let probe = std::fs::File::open(path).and_then(|mut f| f.read_to_end(&mut Vec::new()));
if probe.is_err() { eprintln!("asset unreadable: {}", path); }

Try / catch

settings.read_svg = Box::new(|path| {
    for _ in 0..3 {
        match std::fs::read(path) { Ok(b) => return b, Err(_) => std::thread::sleep(std::time::Duration::from_millis(50)) }
    }
    Vec::new()
});

Prevention

When it happens

Trigger: read_to_end returning Err — e.g. the file is a directory-like special file, hardware/permission error occurs mid-read, or the underlying file was removed/truncated between open and read.

Common situations: Reading from network mounts or removable drives that disconnect, files being overwritten atomically (renamed away) during startup, corrupted filesystems.

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 a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/1c05e0cad6f24b30. Report an issue: GitHub.

Appendix: source

Thrown at widgetry/src/runner.rs:230

            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 {
        self.scale_factor = Some(scale_factor);
        self
    }

View on GitHub (pinned to 0964f29315)