jdx/mise · error
agent ' ' `queue_directories` must not contain empty entries
Error message
agent '{name}' `queue_directories` must not contain empty entries What it means
LaunchdRequest::from_toml iterates the agent's queue_directories list and rejects any entry that is empty or whitespace-only after trimming. Empty entries would produce an invalid WatchPaths entry in the generated plist. The check applies to the raw string, independent of platform path rules.
Solutions
- Remove empty or whitespace-only entries from queue_directories
- Ensure each entry is a real absolute directory path
- If building the list programmatically, filter out empty strings before writing config
Example fix
# before queue_directories = ["/var/spool/mail", ""] # after queue_directories = ["/var/spool/mail"]
Defensive patterns
Strategy: validation
Validate before calling
dirs = agent_cfg.get("queue_directories", [])
assert all(d.strip() for d in dirs), "queue_directories contains an empty entry" Prevention
- Filter empty strings when building directory lists programmatically
- Avoid trailing blank entries when hand-editing arrays
- Validate TOML arrays before deploying
When it happens
Trigger: queue_directories = ["/var/spool/mail", ""] or [" "] — an array containing an empty or whitespace-only element.
Common situations: Trailing commas or placeholder slots left in the directory list; template expansion producing empty strings; hand-editing the array and leaving a blank entry.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- agent ' ' `start_calendar_interval. ` must be between and
- agent ' ' `start_calendar_interval` must set at least one…
- agent ' ' `start_calendar_interval` must not be empty
- agent ' ' cannot set both `keep_alive` and…
- agent ' ' must set a non-empty `program
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/486ac6ba8e68a05e.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/launchd.rs:131
}
let Some(program) = config.program.map(|s| s.trim().to_string()) else {
bail!("agent '{name}' must set `program`");
};
if program.is_empty() {
bail!("agent '{name}' must set a non-empty `program`");
}
if config.keep_alive && config.keep_alive_on_failure {
bail!("agent '{name}' cannot set both `keep_alive` and `keep_alive_on_failure`");
}
if config.nice.is_some_and(|nice| !(-20..=20).contains(&nice)) {
bail!("agent '{name}' `nice` must be between -20 and 20");
}
if let Some(interval) = &config.start_calendar_interval {
interval.validate(&name)?;
}
for dir in &config.queue_directories {
if dir.trim().is_empty() {
bail!("agent '{name}' `queue_directories` must not contain empty entries");
}
// checked against the raw string rather than `Path::is_absolute` on the
// expanded value: the plist is consumed by macOS launchd, so POSIX rules
// apply regardless of the platform parsing the config, and on Windows
// `Path::new("/var/spool").is_absolute()` is false (root, but no prefix)
if !is_absolute_launchd_path(dir) {
bail!(
"agent '{name}' `queue_directories` entry '{dir}' must be an absolute path \
(launchd requires absolute paths; `~` and `~/` are expanded)"
);
}
}
Ok(Self {
label: format!("dev.mise.{name}"),
name,
program,
args: config.args,
run_at_load: config.run_at_load,View on GitHub (pinned to 533346cc37)