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
- 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
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
- 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
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
- overlapping macOS defaults declarations
- [bootstrap.macos.dock].apps: expected a path relative to…
- [bootstrap.macos.dock].apps: expected an absolute or ~/…
- `defaults ` failed
- `defaults ` failed
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)