jdx/mise · error
agent ' ' must set `program
Error message
agent '{name}' must set `program` What it means
LaunchdRequest::from_toml requires every launchd agent to define a `program` field, since launchd needs a command to run. If LaunchdTomlConfig.program is None (missing from the TOML), the function bails with this message. It is a missing-required-field check at config parse time.
Solutions
- Add a `program` key to the agent config pointing at the executable to run
- Remove the agent section if it is not needed
- Verify the TOML section is not shadowed so `program` actually lands in the intended agent
Example fix
# before [agent.backup] keep_alive = true # after [agent.backup] program = "/usr/local/bin/backup.sh" keep_alive = true
Defensive patterns
Strategy: validation
Validate before calling
if "program" not in agent_cfg:
raise ValueError(f"agent '{name}' needs a program") Prevention
- Always pair every agent section with a program key
- Use a config schema requiring `program`
- Review commented-out program lines when editing agent configs
When it happens
Trigger: Defining an [agent.NAME] section without a `program` key, or programmatically constructing LaunchdTomlConfig with program = None.
Common situations: Creating an empty agent stub and forgetting to fill in program; commenting out the program line while keeping the agent section; copying an agent config that relies on a key another version supported.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 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/d732f72354b2da83.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/launchd.rs:115
Differs,
Missing,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct LaunchdStatus {
pub request: LaunchdRequest,
pub path: PathBuf,
pub loaded: bool,
pub state: LaunchdState,
}
impl LaunchdRequest {
pub(crate) fn from_toml(name: String, config: LaunchdTomlConfig) -> Result<Self> {
if !valid_name(&name) {
bail!("agent name '{name}' must contain only letters, numbers, '.', '_', or '-'");
}
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 theView on GitHub (pinned to 533346cc37)