xpzouying/xiaohongshu-mcp · error

hdiutil attach: %v: %s

Error message

hdiutil attach: %v: %s

What it means

On macOS, extractDmg mounts the downloaded .dmg via the external `hdiutil attach` command with -nobrowse and a temporary mountpoint. This error wraps both the exec error and the combined stdout/stderr output when hdiutil fails to mount the image.

Source

Thrown at browser/browser_download.go:310

		_, err = io.Copy(out, rc)
		out.Close()
		rc.Close()
		if err != nil {
			return err
		}
	}
	return nil
}

func extractDmg(archivePath, destDir string) error {
	mountPoint, err := os.MkdirTemp("", "bx-dmg-")
	if err != nil {
		return err
	}
	defer os.RemoveAll(mountPoint)

	if out, err := exec.Command("hdiutil", "attach", archivePath, "-nobrowse", "-mountpoint", mountPoint).CombinedOutput(); err != nil {
		return fmt.Errorf("hdiutil attach: %v: %s", err, out)
	}
	defer exec.Command("hdiutil", "detach", mountPoint, "-quiet").Run()

	var appPath string
	entries, _ := os.ReadDir(mountPoint)
	for _, e := range entries {
		if strings.HasSuffix(e.Name(), ".app") {
			appPath = filepath.Join(mountPoint, e.Name())
			break
		}
	}
	if appPath == "" {
		return fmt.Errorf("dmg 内未找到 .app")
	}
	dstApp := filepath.Join(destDir, filepath.Base(appPath))
	if out, err := exec.Command("cp", "-R", appPath, dstApp).CombinedOutput(); err != nil {
		return fmt.Errorf("拷贝 .app: %v: %s", err, out)
	}

View on GitHub (pinned to 332d196854)

Solutions

  1. Re-download the .dmg (clear cache, re-run EnsureBrowser) — the most common cause is a corrupt/truncated image
  2. Verify the archive passes SHA256 verification (verifySHA256 should have caught corruption, but confirm the cache file wasn't damaged afterwards)
  3. Run hdiutil attach <file> -nobrowse manually to see the full error output
  4. Check free disk space and that /tmp (or the mountpoint parent) is writable
  5. On CI, ensure the runner permits mounting disk images or switch to a zip-based distribution

Example fix

// before
if out, err := exec.Command("hdiutil", "attach", archivePath, "-nobrowse", "-mountpoint", mountPoint).CombinedOutput(); err != nil {
	return fmt.Errorf("hdiutil attach: %v: %s", err, out)
}
// after — verify the image first for a clearer message
if out, err := exec.Command("hdiutil", "imageinfo", archivePath).CombinedOutput(); err != nil {
	return fmt.Errorf("损坏的 dmg (imageinfo 失败): %v: %s", err, out)
}
if out, err := exec.Command("hdiutil", "attach", archivePath, "-nobrowse", "-mountpoint", mountPoint).CombinedOutput(); err != nil {
	return fmt.Errorf("hdiutil attach: %v: %s", err, out)
}
Defensive patterns

Strategy: fallback

Validate before calling

out, err := exec.Command("hdiutil", "imageinfo", dmgPath).CombinedOutput()
if err != nil {
	// dmg 已损坏,先重新下载
}

Try / catch

if err := EnsureBrowser(ctx); err != nil {
	if strings.Contains(err.Error(), "hdiutil attach") {
		// dmg 损坏或被安全策略拦截:清缓存重下,或改用 zip 分发
		os.RemoveAll(cacheDir)
		return EnsureBrowser(ctx)
	}
	return err
}

Prevention

When it happens

Trigger: extractArchive -> extractDmg on macOS runs exec.Command("hdiutil", "attach", archivePath, ...).CombinedOutput() and the command returns a non-zero exit code (corrupt image, no disk image, permissions, security agent blocking).

Common situations: The .dmg download was truncated or corrupted (hdiutil reports 'no mountable file systems'); macOS security policies or MDM block hdiutil; the binary was quarantined and Gatekeeper interferes; running in a CI macOS runner without GUI/permission; disk space exhaustion.

Related errors


AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05). Data as JSON: /api/errors/3b73cc909da08ad9. Report an issue: GitHub.