{"record":{"id":"12c7667d43ea186f","repo":"jdx/mise","slug":"defaults-patch-path-must-not-be-empty-request","errorCode":null,"errorMessage":"defaults patch path must not be empty: {request}","messagePattern":"defaults patch path must not be empty: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/defaults.rs","lineNumber":296,"sourceCode":"            continue;\n        }\n        debug!(\"setting macOS preference {req}\");\n    }\n    if dry_run {\n        return Ok(());\n    }\n    let requests = requests.to_vec();\n    tokio::task::spawn_blocking(move || write_all(&requests)).await?\n}\n\n/// Reject conflicting ownership before inspecting or writing preferences.\nfn validate_requests(requests: &[DefaultsRequest]) -> Result<()> {\n    for (i, request) in requests.iter().enumerate() {\n        if request.dock_apps {\n            dock::paths(&request.value)?;\n        }\n        if let Some(path) = &request.path {\n            eyre::ensure!(\n                !path.is_empty(),\n                \"defaults patch path must not be empty: {request}\"\n            );\n        }\n        for other in &requests[..i] {\n            if canonical_domain(&request.domain) != canonical_domain(&other.domain)\n                || request.key != other.key\n                || request.host != other.host\n            {\n                continue;\n            }\n            let overlaps = match (&request.path, &other.path) {\n                (None, None) => false, // Preserve existing whole-value declarations.\n                (Some(a), Some(b)) => a.starts_with(b) || b.starts_with(a),\n                _ => true,\n            };\n            eyre::ensure!(\n                !overlaps,","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/defaults.rs#L278-L314","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set a non-empty patch path (e.g. \"key.subkey\") in the DefaultsRequest","Omit the path field entirely (None) if you intend to patch the whole domain value","Check config parsing that produces the path — an empty TOML/CLI value likely slipped through"],"exampleFix":"// before\nDefaultsRequest { domain: \"com.apple.dock\", path: Some(String::new()), .. }\n// after\nDefaultsRequest { domain: \"com.apple.dock\", path: Some(\"autohide\".into()), .. }\n// or: path: None to patch the whole domain value","handlingStrategy":"validation","validationCode":"fn validate_defaults_request(req: &DefaultsRequest) -> Result<(), String> {\n    if let Some(p) = &req.path {\n        if p.is_empty() { return Err(format!(\"defaults patch path must not be empty: {}\", req.domain)); }\n    }\n    Ok(())\n}","typeGuard":"fn has_valid_path(req: &DefaultsRequest) -> bool {\n    req.path.as_ref().map_or(true, |p| !p.is_empty())\n}","tryCatchPattern":null,"preventionTips":["Use None instead of Some(String::new()) when no sub-path is intended","Validate config-driven path strings for emptiness at parse time","Check string-splitting logic that builds paths for empty segments"],"tags":["macos","defaults","validation","empty-string"],"backgroundTag":"invalid-argument-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}