jdx/mise · error

`defaults {display}` failed: {}

Error message

`defaults {display}` failed: {}

What it means

Applying [bootstrap.macos.defaults] entries runs 'defaults write <domain> <key> -<type> <value>' per key via 'mise bootstrap macos defaults apply' (or full 'mise bootstrap'); when the macOS defaults command exits non-zero, mise bails with the command rendered as 'defaults <domain> <key> = <value>' plus trimmed stderr. There is no missing-key exemption at write time — a failing write is always an error.

Source

Thrown at src/system/defaults.rs:178

        let mut args = vec!["write".to_string(), req.domain.clone(), req.key.clone()];
        args.extend(req.value.write_args());
        // shell-quoted so the printed command is copy-pasteable even when a
        // string value contains spaces
        let display = shell_words::join(&args);
        if dry_run {
            miseprintln!("defaults {display}");
            continue;
        }
        debug!("$ defaults {display}");
        let output = tokio::process::Command::new("defaults")
            .args(&args)
            .stdin(Stdio::null())
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .output()
            .await?;
        if !output.status.success() {
            eyre::bail!(
                "`defaults {display}` failed: {}",
                String::from_utf8_lossy(&output.stderr).trim()
            );
        }
    }
    Ok(())
}

/// `defaults read-type` + `defaults read` for one key. Returns
/// `(type, raw value)`, or None when the key (or domain) does not exist —
/// both commands exit non-zero for that, which is not an error here.
async fn read(domain: &str, key: &str) -> Result<Option<(String, String)>> {
    let Some(read_type) = defaults_cmd(&["read-type", domain, key]).await? else {
        return Ok(None);
    };
    // "Type is boolean" -> "boolean"
    let read_type = read_type
        .strip_prefix("Type is ")

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Run the exact 'defaults write ...' line from the error manually to see macOS's own complaint
  2. If the domain is MDM-managed, remove that key from [bootstrap.macos.defaults] — it cannot be set declaratively
  3. For corrupt plists: quit the owning app, delete ~/Library/Preferences/<domain>.plist, and re-run bootstrap; for headless runs, bootstrap from a real GUI login session

Example fix

# before
[bootstrap.macos.defaults."com.corp.managed"]
DisableThing = true

# after — key is owned by an MDM profile, manage it out of band
# (remove the entry from mise.toml entirely)
Defensive patterns

Strategy: try-catch

Validate before calling

# preflight: probe writability of each configured domain
defaults write "$DOMAIN" __mise_probe -bool true && defaults delete "$DOMAIN" __mise_probe \
  || echo "domain $DOMAIN not writable — remove it from [bootstrap.macos.defaults]"

Try / catch

Apply defaults per domain ('mise bootstrap macos defaults apply') in scripts and catch non-zero exits: print the failing 'defaults write' line from the log, classify MDM/permission errors as permanent (drop the key from config) and cfprefsd/headless errors as retryable once a GUI session exists.

Prevention

When it happens

Trigger: defaults write failing: the domain/key is managed by an MDM configuration profile and read-only, cfprefsd is unavailable (headless SSH session with no GUI domain), the preferences plist is corrupt, or macOS refuses the type conversion for the key.

Common situations: Corporate Macs with managed preferences; running mise bootstrap over SSH before any GUI login; a plist corrupted after a crash or forced shutdown.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/b4b974088e4c9b09. Report an issue: GitHub.