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

  1. Verify Graphite.exe actually exists at the bundled path printed by the tool before the spawn
  2. Un-quarantine the exe in Windows Defender / choose 'Run anyway' on SmartScreen, or add a build-output exclusion
  3. Move the build output to a shorter path or enable Windows long-path support (group policy)
  4. 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

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


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/01c5d071b67a58b1. Report an issue: GitHub.