jdx/mise · error

defaults patch path must not be empty

Error message

defaults patch path must not be empty: {request}

What it means

Thrown by validate_requests (used by the defaults status, apply, and prepare_writes flows) when a macOS DefaultsRequest includes a patch path that is an empty string. A patch path selects a subkey inside the domain's plist; an empty path is ambiguous and would produce an invalid defaults operation, so it is rejected.

Solutions

  1. Set a non-empty patch path (e.g. "key.subkey") in the DefaultsRequest
  2. Omit the path field entirely (None) if you intend to patch the whole domain value
  3. Check config parsing that produces the path — an empty TOML/CLI value likely slipped through

Example fix

// before
DefaultsRequest { domain: "com.apple.dock", path: Some(String::new()), .. }
// after
DefaultsRequest { domain: "com.apple.dock", path: Some("autohide".into()), .. }
// or: path: None to patch the whole domain value
Defensive patterns

Strategy: validation

Validate before calling

fn validate_defaults_request(req: &DefaultsRequest) -> Result<(), String> {
    if let Some(p) = &req.path {
        if p.is_empty() { return Err(format!("defaults patch path must not be empty: {}", req.domain)); }
    }
    Ok(())
}

Type guard

fn has_valid_path(req: &DefaultsRequest) -> bool {
    req.path.as_ref().map_or(true, |p| !p.is_empty())
}

Prevention

When it happens

Trigger: Constructing a DefaultsRequest with `path: Some("")` (e.g. from parsing config like `path = ""` or splitting an empty key path) and passing it to defaults status/apply/prepare_writes.

Common situations: A bootstrap config where the dot-notation path under a defaults key was omitted, yielding an empty string; string splitting that produces an empty segment; programmatic request building with an uninitialized path.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/12c7667d43ea186f. Report an issue: GitHub.

Appendix: source

Thrown at src/system/defaults.rs:296

            continue;
        }
        debug!("setting macOS preference {req}");
    }
    if dry_run {
        return Ok(());
    }
    let requests = requests.to_vec();
    tokio::task::spawn_blocking(move || write_all(&requests)).await?
}

/// Reject conflicting ownership before inspecting or writing preferences.
fn validate_requests(requests: &[DefaultsRequest]) -> Result<()> {
    for (i, request) in requests.iter().enumerate() {
        if request.dock_apps {
            dock::paths(&request.value)?;
        }
        if let Some(path) = &request.path {
            eyre::ensure!(
                !path.is_empty(),
                "defaults patch path must not be empty: {request}"
            );
        }
        for other in &requests[..i] {
            if canonical_domain(&request.domain) != canonical_domain(&other.domain)
                || request.key != other.key
                || request.host != other.host
            {
                continue;
            }
            let overlaps = match (&request.path, &other.path) {
                (None, None) => false, // Preserve existing whole-value declarations.
                (Some(a), Some(b)) => a.starts_with(b) || b.starts_with(a),
                _ => true,
            };
            eyre::ensure!(
                !overlaps,

View on GitHub (pinned to 533346cc37)