tauri-apps/tauri · error · std::io::Error

{error_message}: {e}

Error message

{error_message}: {e}

What it means

tauri-macos-sign shells out to macOS tools (codesign, security, hdiutil, xcrun). assert_command takes the spawn Result of the command; this formatted branch ('{error_message}: {e}') fires only when the process could not be launched at all — the io::Error kind and OS message are preserved alongside the caller's prefix. A tool that starts but exits non-zero takes the other branch (bare io::Error::other(error_message)), so this variant specifically means launch failure.

Source

Thrown at crates/tauri-macos-sign/src/lib.rs:362

  let decoded = base64::engine::general_purpose::STANDARD
    .decode(&cleaned)
    .map_err(Error::Base64Decode)?;

  std::fs::write(out_path, &decoded).map_err(|error| Error::Fs {
    context: "failed to write decoded certificate",
    path: out_path.to_path_buf(),
    error,
  })?;

  Ok(())
}

fn assert_command(
  response: std::result::Result<std::process::ExitStatus, std::io::Error>,
  error_message: &str,
) -> std::io::Result<()> {
  let status =
    response.map_err(|e| std::io::Error::new(e.kind(), format!("{error_message}: {e}")))?;
  if !status.success() {
    Err(std::io::Error::other(error_message))
  } else {
    Ok(())
  }
}

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Install Command Line Tools: `xcode-select --install` (or full Xcode)
  2. Verify the tool resolves: `xcrun --find codesign` and `codesign -h`
  3. Reset a stale developer directory: `sudo xcode-select -r`
  4. In CI, ensure PATH includes /usr/bin and set DEVELOPER_DIR explicitly to the CLT path

Example fix

# before: signing fails with 'failed to run codesign: ...'
xcode-select -p   # missing or broken path
# after:
xcode-select --install
xcode-select -p   # /Library/Developer/CommandLineTools
Defensive patterns

Strategy: validation

Validate before calling

// preflight: ensure the macOS tool exists before signing
fn require_tool(name: &str) -> std::io::Result<()> {
    let ok = std::process::Command::new("xcrun")
        .arg("--find")
        .arg(name)
        .output()
        .map(|o| o.status.success())
        .unwrap_or(false);
    if ok {
        Ok(())
    } else {
        Err(std::io::Error::new(
            std::io::ErrorKind::NotFound,
            format!("{name} not found; run `xcode-select --install`"),
        ))
    }
}

Try / catch

match sign_app(&app_path) {
    Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
        eprintln!("signing tool unavailable — install Xcode Command Line Tools: {e}");
        std::process::exit(1);
    }
    Err(e) => return Err(e.into()),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Signing or notarizing when the tool binary cannot start: Xcode Command Line Tools not installed, xcode-select pointing at a broken/missing developer directory, PATH stripped in CI or launchd environments, or an exec-format/architecture mismatch.

Common situations: Fresh macOS CI runners without Command Line Tools; headless build agents; scripts run from GUI apps with minimal PATH; a macOS/Xcode upgrade that invalidated the active developer directory.

Related errors


AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20). Data as JSON: /api/errors/0660491eb49ca70f. Report an issue: GitHub.