affaan-m/ECC · error · anyhow::Error

invalid cron expression `{trimmed}`: expected 5, 6, or 7 fie

Error message

invalid cron expression `{trimmed}`: expected 5, 6, or 7 fields but found {fields}

What it means

Thrown by validate_schedule_cron_expr when the cron expression, split on whitespace, does not have 5, 6, or 7 fields. The importer supports standard 5-field cron (to which it prepends '0 ' to make a 6-field expression with seconds), 6-field, and 7-field (with seconds and years) forms. Any other field count is ambiguous and rejected before being passed to the cron parser.

Source

Thrown at ecc2/src/main.rs:5971

}

fn shell_quote_double(value: &str) -> String {
    format!(
        "\"{}\"",
        value
            .replace('\\', "\\\\")
            .replace('"', "\\\"")
            .replace('\n', "\\n")
    )
}

fn validate_schedule_cron_expr(expr: &str) -> Result<()> {
    let trimmed = expr.trim();
    let normalized = match trimmed.split_whitespace().count() {
        5 => format!("0 {trimmed}"),
        6 | 7 => trimmed.to_string(),
        fields => {
            anyhow::bail!(
                "invalid cron expression `{trimmed}`: expected 5, 6, or 7 fields but found {fields}"
            )
        }
    };
    <cron::Schedule as std::str::FromStr>::from_str(&normalized)
        .with_context(|| format!("invalid cron expression `{trimmed}`"))?;
    Ok(())
}

fn build_legacy_schedule_add_command(draft: &LegacyScheduleDraft) -> Option<String> {
    let cron_expr = draft.cron_expr.as_deref()?;
    let task = draft.task.as_deref()?;
    let mut parts = vec![
        "ecc schedule add".to_string(),
        format!("--cron {}", shell_quote_double(cron_expr)),
        format!("--task {}", shell_quote_double(task)),
    ];
    if let Some(agent) = draft.agent.as_deref() {

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Rewrite the expression as standard 5-field cron 'minute hour day month weekday' (e.g. '0 2 * * *'), or 6/7-field if you need seconds/years.
  2. Remove inline comments or extra tokens so whitespace splitting yields exactly 5, 6, or 7 fields.
  3. Replace human-readable phrases ('every 5 minutes', '@hourly') with their cron equivalent before importing.
  4. Validate locally with a cron checker before re-running the importer.

Example fix

# before
"cron": "every 5 minutes"

# after
"cron": "*/5 * * * *"
Defensive patterns

Strategy: validation

Validate before calling

fn cron_field_count_ok(expr: &str) -> bool {
    matches!(expr.trim().split_whitespace().count(), 5 | 6 | 7)
}

// usage before import
if !cron_field_count_ok(&entry.cron) {
    return Err(anyhow!("cron expr has wrong field count: {}", entry.cron));
}

Prevention

When it happens

Trigger: A legacy schedule entry carries a cron expression with too few or too many fields, e.g. '* * *' (3 fields), '0 0 * * 0 extra junk' (6 non-standard tokens), or 'every 5 minutes' (a human-readable string, not cron syntax).

Common situations: Migrating from a tool that used a non-standard schedule format (English phrases, intervals like '@daily' not supported here, or quarts-style 6-field without seconds normalization); copy-paste errors; trailing comments or spaces that change the token count.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/85d88d1b49690110. Report an issue: GitHub.