jdx/mise · error
agent '{agent_name}' `start_calendar_interval` must set at l
Error message
agent '{agent_name}' `start_calendar_interval` must set at least one field What it means
A single-table start_calendar_interval must set at least one of minute, hour, day, weekday, or month — launchd treats unset fields as wildcards, but a table where every field is unset is meaningless. LaunchdCalendarInterval::validate rejects that case, then range-checks each set field (minute 0-59, hour 0-23, day 1-31, weekday 0-7, month 1-12). The whole agent is skipped with a warning.
Source
Thrown at src/system/launchd.rs:158
queue_directories: config.queue_directories,
environment: config.environment,
working_directory: config.working_directory,
stdout_path: config.stdout_path,
stderr_path: config.stderr_path,
kickstart: config.kickstart,
})
}
}
impl LaunchdCalendarInterval {
fn validate(&self, agent_name: &str) -> Result<()> {
if self.minute.is_none()
&& self.hour.is_none()
&& self.day.is_none()
&& self.weekday.is_none()
&& self.month.is_none()
{
bail!("agent '{agent_name}' `start_calendar_interval` must set at least one field");
}
validate_range(agent_name, "minute", self.minute, 0, 59)?;
validate_range(agent_name, "hour", self.hour, 0, 23)?;
validate_range(agent_name, "day", self.day, 1, 31)?;
validate_range(agent_name, "weekday", self.weekday, 0, 7)?;
validate_range(agent_name, "month", self.month, 1, 12)?;
Ok(())
}
}
impl LaunchdCalendarIntervals {
fn validate(&self, agent_name: &str) -> Result<()> {
match self {
Self::Single(interval) => interval.validate(agent_name),
Self::Multiple(intervals) => {
if intervals.is_empty() {
bail!("agent '{agent_name}' `start_calendar_interval` must not be empty");
}View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Set at least one recognized field (minute/hour/day/weekday/month) with lowercase keys
- Use 24-hour hour values and launchd ranges (minute 0-59, hour 0-23, day 1-31, weekday 0-7, month 1-12)
- If no schedule is needed, remove start_calendar_interval and rely on run_at_load/keep_alive
Example fix
# before [bootstrap.macos.launchd.agents.backup.start_calendar_interval] second = 30 # after [bootstrap.macos.launchd.agents.backup.start_calendar_interval] hour = 3 minute = 30
Defensive patterns
Strategy: validation
Validate before calling
python3 - <<'EOF'
import tomllib,sys
c=tomllib.load(open('mise.toml','rb'))
ranges={'minute':(0,59),'hour':(0,23),'day':(1,31),'weekday':(0,7),'month':(1,12)}
for name,agent in (c.get('bootstrap',{}).get('macos',{}).get('launchd',{}).get('agents',{}) or {}).items():
iv=agent.get('start_calendar_interval')
ivs=iv if isinstance(iv,list) else [iv] if isinstance(iv,dict) else []
for i in ivs:
if not i or not any(k in i for k in ranges): sys.exit(f'agent {name}: interval sets no recognized field')
for k,v in i.items():
if k in ranges and not (ranges[k][0]<=v<=ranges[k][1]): sys.exit(f'agent {name}: {k}={v} out of range')
EOF Prevention
- Always set at least one of minute/hour/day/weekday/month per interval table
- Use lowercase launchd field names; there is no 'second' field
- Remember ranges: minute 0-59, hour 0-23 (24h), day 1-31, weekday 0-7, month 1-12
When it happens
Trigger: Writing an empty [bootstrap.macos.launchd.agents.<name>.start_calendar_interval] table, or one containing only unrecognized keys (e.g. second = 30, or capitalized Minute), which deserialize as unset.
Common situations: Placeholder tables meant to be filled in later; expecting cron-string or 'second' syntax like other schedulers; key-name casing mistakes that silently deserialize to defaults.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- agent name '{name}' must contain only letters, numbers, '.',
- agent '{agent_name}' `start_calendar_interval` must not be e
- agent '{name}' must set `program`
- agent '{name}' must set a non-empty `program`
- agent '{name}' `queue_directories` must not contain empty en
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/11cd101140f57aec.
Report an issue: GitHub.