emilk/egui · error
Failed to save screenshot to {path:?}: {err}
Error message
Failed to save screenshot to {path:?}: {err} What it means
In eframe's glow integration, when the app exits with `screenshot_on_save`/`--screenshot` behavior, `save_screenshot_and_exit` writes the captured framebuffer to disk with the `image` crate. If `image::save_buffer` fails (bad path, unwritable directory, I/O error), the code panics with this message before calling `std::process::exit(0)`.
Source
Thrown at crates/eframe/src/native/glow_integration.rs:1773
fn save_screenshot_and_exit(
path: &str,
painter: &egui_glow::Painter,
screen_size_in_pixels: [u32; 2],
) {
assert!(
egui::load::has_extension(path, "png"),
"Expected EFRAME_SCREENSHOT_TO to end with '.png', got {path:?}"
);
let screenshot = painter.read_screen_rgba(screen_size_in_pixels);
image::save_buffer(
path,
screenshot.as_raw(),
screenshot.width() as u32,
screenshot.height() as u32,
image::ColorType::Rgba8,
)
.unwrap_or_else(|err| {
panic!("Failed to save screenshot to {path:?}: {err}");
});
log::info!("Screenshot saved to {path:?}.");
#[expect(clippy::exit)]
std::process::exit(0);
}
View on GitHub (pinned to 441971a776)
Solutions
- Ensure the parent directory of the screenshot path exists (create it with `std::fs::create_dir_all` before running).
- Verify the path is writable by the user running the app (fix permissions or choose another output location).
- Check the embedded `err` in the panic message for the underlying I/O cause (e.g. NotFound, PermissionDenied) and address it.
- If path is constructed at runtime, log/validate it before the run; use an absolute path to avoid CWD surprises in CI.
Example fix
// before
std::fs::create_dir("screenshots")?; // fails if exists, or wrong dir
// after
std::fs::create_dir_all("screenshots/shots")?; // ensure full path exists before screenshot mode writes there Defensive patterns
Strategy: validation
Validate before calling
let path = std::path::Path::new("shots/app.png");
if let Some(dir) = path.parent() {
std::fs::create_dir_all(dir).expect("create screenshot dir");
}
assert!(!dir_is_readonly(dir), "screenshot dir must be writable"); Try / catch
// if writing screenshots yourself:
if let Err(err) = image::save_buffer(path, data, w, h, image::ColorType::Rgba8) {
log::error!("screenshot save failed: {err}");
// fallback path or exit non-zero without panic
} Prevention
- Always create the output directory (create_dir_all) before enabling screenshot mode.
- Use absolute paths for screenshot output so CI/daemon CWD differences can't break writes.
- Check disk space and permissions in CI before screenshot tests.
- Pick a widely-supported extension (.png) so the image encoder is available.
When it happens
Trigger: Running an eframe app in screenshot mode (e.g. `NativeOptions { screenshot_on_save: true }` or CLI screenshot flag) where the target `path` is invalid, the parent directory doesn't exist, the process lacks write permission, or the disk is full so `image::save_buffer` returns Err.
Common situations: CI pipelines running headless screenshot tests with a relative output path that resolves to a non-existent directory; read-only containers passing an unwritable path; typos in the screenshot file path or unsupported extension.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Failed to create staging buffer for index data. Index count:
- Failed to create staging buffer for vertex data. Vertex coun
- Plugin of type {:?} not found
- Window did not show
- Window was collapsed
AI-assisted analysis of emilk/egui@441971a776 (2026-09-12).
Data as JSON: /api/errors/d5964a92597c03d6.
Report an issue: GitHub.