jdx/mise · error

overlapping macOS defaults declarations

Error message

overlapping macOS defaults declarations: {other}; {request}

What it means

Thrown by validate_requests when two macOS defaults requests target the same canonical domain with overlapping patch paths. If both requests have paths and one is a prefix of the other (e.g. "a" and "a.b"), or only one has a path (mixing whole-domain and sub-path patches), the writes would conflict; the loader refuses rather than applying ambiguous precedence. Two whole-domain requests (both paths None) are allowed to preserve existing behavior.

Solutions

  1. Merge the overlapping declarations into a single request per domain
  2. Make sibling paths non-overlapping (e.g. patch "a.c" and "a.b", not "a" and "a.b")
  3. Remove the duplicate domain entry from one of the config files
  4. If both declarations are whole-domain (no path), leave as-is — those are intentionally allowed

Example fix

// before: two requests on com.apple.dock
{ domain: "com.apple.dock", path: Some("tilesize") }
{ domain: "com.apple.dock", path: Some("tilesize.orientation") }
// after: non-overlapping paths
{ domain: "com.apple.dock", path: Some("tilesize") }
{ domain: "com.apple.dock", path: Some("orientation") }
Defensive patterns

Strategy: validation

Validate before calling

fn validate_no_overlap(reqs: &[DefaultsRequest]) -> Result<(), String> {
    for i in 0..reqs.len() {
        for j in 0..i {
            let (a, b) = (&reqs[i], &reqs[j]);
            let overlaps = match (&a.path, &b.path) {
                (None, None) => false,
                (Some(x), Some(y)) => x.starts_with(y.as_str()) || y.starts_with(x.as_str()),
                _ => true,
            };
            if overlaps && a.domain == b.domain {
                return Err(format!("overlapping defaults: {} and {}", a.domain, b.domain));
            }
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: Passing two DefaultsRequests with equal canonical domains to defaults status/apply/prepare_writes where path pairs are (Some,Some) prefix-related or (Some,None)/(None,Some).

Common situations: Declaring the same macOS domain twice in bootstrap config — once at the top level and once with a subkey path; two config files (user + project) both patching com.apple.dock; generated requests that duplicate a domain with refined paths.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/system/defaults.rs:313

        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,
                "overlapping macOS defaults declarations: {other}; {request}"
            );
        }
    }
    Ok(())
}

fn selected_value<'a>(
    mut current: Option<&'a plist::Value>,
    request: &DefaultsRequest,
) -> Result<Option<&'a plist::Value>> {
    if let Some(path) = &request.path {
        for component in path {
            current = match current {
                Some(plist::Value::Dictionary(dict)) => dict.get(component),
                None => return Ok(None),
                Some(_) => eyre::bail!("expected dictionary along defaults patch path: {request}"),

View on GitHub (pinned to 533346cc37)