janhq/jan · warning
Executable must have a parent directory
Error message
Executable must have a parent directory
What it means
This is a panic (.expect) from Path::parent() on the exe path obtained from current_exe(). parent() returns None only when the path is a bare root or a single component with no directory separator. Since current_exe() returns absolute paths on all supported platforms, this panic is effectively unreachable in practice — it exists as a safety invariant assertion.
Source
Thrown at src-tauri/src/core/mcp/helpers.rs:407
}
Err(e) => {
log::error!("Failed to start MCP server {name} on first attempt: {e}");
Err(e)
}
}
}
async fn schedule_mcp_start_task<R: Runtime>(
app: tauri::AppHandle<R>,
servers: SharedMcpServers,
name: String,
config: Value,
) -> Result<(), String> {
let app_path = get_jan_data_folder_path(app.clone());
let exe_path = env::current_exe().expect("Failed to get current exe path");
let exe_parent_path = exe_path
.parent()
.expect("Executable must have a parent directory");
let bin_path = exe_parent_path.to_path_buf();
let config_params = extract_command_args(&config)
.ok_or_else(|| format!("Failed to extract command args from config for {name}"))?;
if let (Some("http"), Some(url)) = (
config_params.transport_type.as_deref(),
config_params.url.clone(),
) {
let transport = StreamableHttpClientTransport::with_client(
reqwest::Client::builder()
.default_headers({
// Map envs to request headers
let mut headers: tauri::http::HeaderMap = reqwest::header::HeaderMap::new();
for (key, value) in config_params.headers.iter() {
if let Some(v_str) = value.as_str() {
// Try to map env keys to HTTP header names (case-insensitive)
// Most HTTP headers are Title-Case, so we try to convertView on GitHub (pinned to fad3f12a14)
Solutions
- Replace .expect with unwrap_or to fall back to the current directory.
- Log a warning and use std::env::current_dir() if parent is None.
- This is a defensive assertion — no user action is needed unless it actually fires.
Example fix
// before
let exe_parent_path = exe_path.parent().expect("Executable must have a parent directory");
// after
let exe_parent_path = exe_path.parent().unwrap_or_else(|| {
log::warn!("exe path has no parent; using current dir");
std::env::current_dir().unwrap_or_default().as_path()
}); Defensive patterns
Strategy: fallback
Validate before calling
// Validate the exe path has a parent before using it
fn exe_parent_or_cwd(exe: &Path) -> PathBuf {
exe.parent()
.map(|p| p.to_path_buf())
.unwrap_or_else(|| {
log::warn!("exe path has no parent component: {}", exe.display());
std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."))
})
} Try / catch
// Replace .expect with a fallback
let bin_path = match exe_path.parent() {
Some(p) => p.to_path_buf(),
None => {
log::warn!("exe path has no parent; using current working directory");
std::env::current_dir().unwrap_or_default()
}
}; Prevention
- Use unwrap_or with a fallback rather than expect for path operations.
- This is a defensive assertion — monitor logs if it fires to detect exotic platform issues.
- Cache the parent path alongside the exe path at startup.
When it happens
Trigger: current_exe() somehow returns a path like "/" or a bare filename with no directory component. A custom platform or exotic FS where the path representation lacks a parent. Theoretically impossible on standard Linux/macOS/Windows where current_exe always yields a full path.
Common situations: Not encountered in real usage. Would only manifest on deeply unusual platforms or after a std library bug. Listed here for completeness.
Related errors
- Failed to serialize MCP settings
- Failed to get current exe path
- Failed to get app data dir
- Jan app not found at {jan_app_path}
- cannot resolve current exe
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/94395e749f508211.
Report an issue: GitHub.