jdx/mise · error

agent ' ' `start_calendar_interval` must set at least one…

Error message

agent '{agent_name}' `start_calendar_interval` must set at least one field

What it means

This error is thrown during launchd agent plist validation when a `StartCalendarInterval` entry has no calendar fields set at all. launchd requires at least one of minute, hour, day, weekday, or month to be specified; an entry with none of them would never fire and is treated as a config mistake. The library fails fast at validation rather than installing a broken agent.

Solutions

  1. Set at least one calendar field, e.g. `minute = 0` and `hour = 3` for a 3:00 AM daily run.
  2. If you meant to disable the schedule, remove the entire `start_calendar_interval` key instead of emptying it.
  3. If you want interval-based rather than calendar-based scheduling, use `start_interval` (seconds) instead.
  4. Run the config through validation locally (e.g. `mise doctor` or the relevant validate path) before applying the agent.

Example fix

# before
[agents.backup.system.start_calendar_interval]

# after
[agents.backup.system.start_calendar_interval]
minute = 0
hour = 3
Defensive patterns

Strategy: validation

Validate before calling

const REQUIRED_FIELDS = ['minute','hour','day','weekday','month'];
function validateCalendarInterval(interval) {
  if (!REQUIRED_FIELDS.some(f => interval[f] !== undefined)) {
    throw new Error('start_calendar_interval must set at least one field');
  }
}

Type guard

function hasCalendarField(i) {
  return ['minute','hour','day','weekday','month'].some(f => i?.[f] !== undefined);
}

Prevention

When it happens

Trigger: Declaring a launchd agent with `start_calendar_interval` set to an object where every field (minute, hour, day, weekday, month) is None/omitted; e.g. `[agents.x.system] start_calendar_interval = {}` or an empty table entry.

Common situations: Hand-editing a mise.toml agent definition and leaving a placeholder empty table; deleting all fields from a schedule intending to disable it instead of removing the key; copying an example config and stripping fields.

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


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/11cd101140f57aec. Report an issue: GitHub.

Appendix: source

Thrown at src/system/launchd.rs:174

            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 533346cc37)