jdx/mise · error

agent '{agent_name}' `start_calendar_interval.{field}` must

Error message

agent '{agent_name}' `start_calendar_interval.{field}` must be between {min} and {max}

What it means

This error is thrown by validate_range while validating a launchd agent's start_calendar_interval entry. launchd restricts each calendar field (minute, hour, day, weekday, month) to a fixed numeric range, and the configured value fell outside that range. It is a user-facing config validation guard so the bad value is rejected before a plist is written and launchctl fails later.

Source

Thrown at src/system/launchd.rs:212

                    interval.validate(agent_name)?;
                }
                Ok(())
            }
        }
    }
}

fn validate_range(
    agent_name: &str,
    field: &str,
    value: Option<u8>,
    min: u8,
    max: u8,
) -> Result<()> {
    if let Some(value) = value
        && !(min..=max).contains(&value)
    {
        bail!(
            "agent '{agent_name}' `start_calendar_interval.{field}` must be between {min} and {max}"
        );
    }
    Ok(())
}

impl std::fmt::Display for LaunchdRequest {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{} ({})", self.name, self.label)
    }
}

pub(crate) fn is_available() -> bool {
    cfg!(target_os = "macos") && crate::file::which("launchctl").is_some()
}

pub(crate) fn unavailable_reason() -> String {
    if cfg!(target_os = "macos") {

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Fix the out-of-range field in the agent's start_calendar_interval config to be within launchd's documented range (minute 0-59, hour 0-23, day 1-31, weekday 0-7, month 1-12).
  2. If you intended a wildcard, omit the field entirely instead of using an out-of-range sentinel value.
  3. If generating values in code, clamp/validate them before writing the config.
  4. Re-run the apply/validate command to confirm the value passes.

Example fix

// before
[[start_calendar_interval]]
minute = 61
// after
[[start_calendar_interval]]
minute = 59
Defensive patterns

Strategy: validation

Validate before calling

const RANGES: &[(&str, u8, u8)] = &[
    ("minute", 0, 59), ("hour", 0, 23), ("day", 1, 31),
    ("weekday", 0, 7), ("month", 1, 12),
];
fn validate_schedule(entry: &Schedule) -> Result<(), String> {
    for (field, min, max) in RANGES {
        if let Some(v) = entry.get(field) {
            if *v < *min || *v > *max {
                return Err(format!("{} must be between {} and {}", field, min, max));
            }
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: Calling validate (via the launchd agent apply path) with a start_calendar_interval field whose u8 value is < min or > max for that field, e.g. minute: 60 (valid 0-59), hour: 24 (valid 0-23), day: 32, weekday: 8, month: 13.

Common situations: Hand-edited config where the author confuses 1-based vs 0-based fields (month 1-12, weekday 0-7 in launchd), copy-pasting cron values that permit 0-6 weekdays, or generating schedules programmatically and off-by-one errors.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/7549826ffb3c58c1. Report an issue: GitHub.