jdx/mise · error
the embedded notification helper is not Developer ID signed
Error message
the embedded notification helper is not Developer ID signed
What it means
macOS notification delivery uses an embedded helper app, which must be signed with a Developer ID for the system to display notifications from it. notification() bails out when the bundled app does not pass the release_signed() check (absent or non-Developer-ID code signature), rather than attempting delivery that macOS would silently drop.
Source
Thrown at src/system/history/notify/macos.rs:51
// running helper. The bundle identifier remains stable across versions.
let fingerprint = crate::hash::hash_to_str(&(HELPER, INFO, ICON, CODE_RESOURCES));
root.join(fingerprint).join("mise.app")
}
fn executable(app: &Path) -> PathBuf {
app.join("Contents/MacOS/mise-notify")
}
fn complete(app: &Path) -> bool {
executable(app).is_file()
&& app.join("Contents/Info.plist").is_file()
&& app.join("Contents/Resources/mise.icns").is_file()
&& app.join("Contents/_CodeSignature/CodeResources").is_file()
}
pub(super) fn notification(title: &str, body: &str) -> Result<Command> {
if !release_signed() {
bail!("the embedded notification helper is not Developer ID signed");
}
let app = ensure_app(&crate::dirs::DATA.join("notifications"))?;
Ok(notification_command(&app, title, body))
}
fn notification_command(app: &Path, title: &str, body: &str) -> Command {
let mut command = Command::new(executable(app));
command.args([title, body]);
command
}
fn ensure_app(root: &Path) -> Result<PathBuf> {
let app = app_path(root);
if complete(&app) {
return Ok(app);
}
crate::file::create_dir_all(root)?;
let mut lock = fslock::LockFile::open(&root.join("install.lock"))?;View on GitHub (pinned to afd2eddd3a)
Solutions
- Install an official Developer ID-signed mise release instead of a locally built binary.
- Re-sign the helper app with a Developer ID certificate (codesign --sign 'Developer ID Application: ...').
- Verify the bundle contains Contents/Resources/mise.icns and Contents/_CodeSignature/CodeResources; re-extract/reinstall the app bundle if missing.
- Disable or skip notification delivery in dev builds (build with the notification feature off) if signing is not available.
Example fix
// before: ad-hoc local build $ cargo build --features notifications # helper is ad-hoc signed -> error // after: official release $ mise run install-dev # or install a signed release whose helper passes release_signed()
Defensive patterns
Strategy: fallback
Validate before calling
// check the bundle before attempting notification
let signed = app.join("Contents/_CodeSignature/CodeResources").is_file()
&& app.join("Contents/Resources/mise.icns").is_file(); Try / catch
match notify::notification(&title, &body) {
Err(e) if e.to_string().contains("not Developer ID signed") => {
eprintln!("notifications unavailable: {e}; falling back to log");
}
other => other?,
} Prevention
- Use official signed releases in environments where notifications matter.
- Keep the helper bundle intact (don't copy files piecemeal).
- Detect dev builds early and skip notification features.
When it happens
Trigger: Requesting a notification when the helper app bundle fails release_signed(): the _CodeSignature/CodeResources file or the mise.icns resource is missing, or the app is signed with an ad-hoc/development identity instead of Developer ID.
Common situations: Running a locally built (cargo build) mise binary whose embedded helper is not Developer ID signed; a broken or partial app bundle in the data directory; Apple notarization/signing stripped by copying files manually.
Related errors
- another process is installing the mise notification helper
- macOS release targets cannot declare a libc family
- `defaults {display}` failed: {}
- `defaults {}` failed: {}
- ditto failed copying {} to {}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/4e28717ebd31fd79.
Report an issue: GitHub.