GraphiteEditor/Graphite · error
failed to open app
Error message
failed to open app
What it means
Panic in the Windows bundler's convenience launcher: after building and copying the Graphite.exe bundle, if invoked with the 'open' CLI subcommand it spawns the bundled executable via run_command. The expect fires when the child process cannot be spawned at all (missing exe, permission denied, OS-level blocking), not when the app itself later crashes.
Source
Thrown at desktop/bundle/src/win.rs:18
use std::error::Error;
use std::fs;
use std::path::{Path, PathBuf};
use crate::common::*;
const EXECUTABLE: &str = "Graphite.exe";
pub fn main() -> Result<(), Box<dyn Error>> {
let app_bin = build_bin("graphite-desktop-platform-win", None, None)?;
let executable = bundle(&profile_path(), &app_bin);
// TODO: Consider adding more useful cli
let args: Vec<String> = std::env::args().collect();
if let Some(pos) = args.iter().position(|a| a == "open") {
let extra_args: Vec<&str> = args[pos + 1..].iter().map(|s| s.as_str()).collect();
run_command(&executable.to_string_lossy(), &extra_args).expect("failed to open app")
}
Ok(())
}
fn bundle(out_dir: &Path, app_bin: &Path) -> PathBuf {
let app_dir = out_dir.join(APP_NAME);
clean_dir(&app_dir);
copy_dir(&cef_path(), &app_dir);
if let Err(e) = remove_unnecessary_cef_files(&app_dir) {
eprintln!("Failed to remove unnecessary CEF files: {}", e);
}
let bin_path = app_dir.join(EXECUTABLE);
fs::copy(app_bin, &bin_path).unwrap();View on GitHub (pinned to c507b35645)
Solutions
- Verify Graphite.exe actually exists at the bundled path printed by the tool before the spawn
- Un-quarantine the exe in Windows Defender / choose 'Run anyway' on SmartScreen, or add a build-output exclusion
- Move the build output to a shorter path or enable Windows long-path support (group policy)
- Launch Graphite.exe manually from Explorer to see the real OS error (missing DLL, blocked, etc.)
Example fix
// before
run_command(&executable.to_string_lossy(), &extra_args).expect("failed to open app")
// after
if let Err(e) = run_command(&executable.to_string_lossy(), &extra_args) {
eprintln!("failed to open app at {}: {e}", executable.display());
std::process::exit(1);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the exe exists and is executable before spawning
let exe = bundle(&profile_path(), &app_bin).join(EXECUTABLE);
if !exe.is_file() {
eprintln!("bundled executable missing at {} (antivirus quarantine?)", exe.display());
std::process::exit(1);
} Try / catch
match run_command(&executable.to_string_lossy(), &extra_args) {
Ok(()) => {}
Err(e) => {
eprintln!("failed to open app at {}: {e}", executable.display());
std::process::exit(1);
}
} Prevention
- Add the build output directory to antivirus exclusions or accept the SmartScreen prompt for local builds
- Keep bundle output paths short to stay under Windows MAX_PATH
- Log the full exe path alongside the spawn error to distinguish missing exe from blocked execution
When it happens
Trigger: Graphite.exe is missing from the just-bundled output (CEF runtime copy failed or antivirus quarantined it); the exe path exceeds Windows MAX_PATH limits; SmartScreen/antivirus blocks execution of the unsigned fresh build; execute permission is missing on the exe.
Common situations: Windows Defender or SmartScreen quarantining an unsigned freshly built executable; building into deeply nested directories that exceed the 260-character path limit without long-path support enabled; running the bundle from a network share or restricted folder.
Related errors
- failed to create app resource dir
- failed to copy icon file
- Failed to compile Windows resources
- CreateWindowExW failed
- InvalidData
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/01c5d071b67a58b1.
Report an issue: GitHub.