BigPizzaV3/CodexPlusPlus · error
打开 DMG 失败:
Error message
打开 DMG 失败:{error} What it means
On macOS, launch_installer opens the downloaded .dmg via the system 'open' command. If spawning 'open' fails, the io error is mapped to 打开 DMG 失败:{error}. Note that on any non-Windows, non-macOS platform the function instead throws the unrelated '当前平台不支持启动安装包' error.
Solutions
- Confirm /usr/bin/open exists and works: run `open` from a terminal.
- Verify the .dmg still exists at the reported installer_path; re-download via perform_update if a cleaner removed it.
- Open the .dmg manually with Finder or `open <path>` to complete the update.
- Retry perform_update — spawn failures from transient resource limits usually clear.
- If 'open' is genuinely unavailable, mount the .dmg with hdiutil attach and copy the app manually.
Example fix
// before
let install = perform_update(&release, &dir).await?; // panics flow on 打开 DMG 失败
// after
match perform_update(&release, &dir).await {
Ok(i) => ..., // i.launched == true on success
Err(e) if e.to_string().contains("打开 DMG 失败") => {
eprintln!("auto-open failed: {e}; mount {} with hdiutil/Finder", expected_dmg.display());
}
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
fn dmg_openable(path: &std::path::Path) -> bool {
path.is_file()
&& std::process::Command::new("open")
.arg("--help")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
} Try / catch
match perform_update(&release, &dir).await {
Ok(install) => Ok(install),
Err(e) if e.to_string().contains("打开 DMG 失败") => {
eprintln!("auto-open failed: {e}; mount {} via Finder or `hdiutil attach`", expected_dmg.display());
Err(e)
}
Err(e) => Err(e),
} Prevention
- Don't remove the download directory between download and launch — cleaners can race the updater.
- Keep the dmg path intact and verify it exists before invoking the update flow.
- On macOS ensure the process environment can spawn /usr/bin/open (avoid broken PATH in launchd contexts).
- Provide the dmg path in the error UI so users can finish the install manually.
When it happens
Trigger: Calling perform_update on macOS when: the 'open' binary is missing from PATH (rare, broken/minimal environment), spawn fails due to resource limits, or the downloaded path was removed before launch. The .dmg file itself opening-then-failing in Finder is NOT this error — only the spawn failure is.
Common situations: Running the app in a sandboxed/odd environment without /usr/bin/open; installer file deleted by a cleaner between download and launch; disk-full or fork-limit conditions preventing process creation.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/5603e8e0eb0abdd5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/update.rs:427
pub fn launch_installer(path: &Path) -> anyhow::Result<()> {
#[cfg(windows)]
{
use std::os::windows::process::CommandExt;
std::process::Command::new(path)
.creation_flags(crate::windows_integration::CREATE_NO_WINDOW)
.spawn()
.map(|_| ())
.map_err(|error| anyhow::anyhow!("启动安装包失败:{error}"))
}
#[cfg(target_os = "macos")]
{
std::process::Command::new("open")
.arg(path)
.spawn()
.map(|_| ())
.map_err(|error| anyhow::anyhow!("打开 DMG 失败:{error}"))
}
#[cfg(all(not(windows), not(target_os = "macos")))]
{
let _ = path;
anyhow::bail!("当前平台不支持启动安装包")
}
}
View on GitHub (pinned to b1ed92e5e4)