{"record":{"id":"33bd0387c52d7a96","repo":"affaan-m/ECC","slug":"invalid-cron-expression-trimmed-expected-5-6-33bd03","errorCode":null,"errorMessage":"invalid cron expression `{trimmed}`: expected 5, 6, or 7 fields but found {fields}","messagePattern":"invalid cron expression `(.+?)`: expected 5, 6, or 7 fields but found (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/manager.rs","lineNumber":2365,"sourceCode":"}\n\nfn resolve_session(db: &StateStore, id: &str) -> Result<Session> {\n    let session = if id == \"latest\" {\n        db.get_latest_session()?\n    } else {\n        db.get_session(id)?\n    };\n\n    session.ok_or_else(|| anyhow::anyhow!(\"Session not found: {id}\"))\n}\n\nfn parse_cron_schedule(expr: &str) -> Result<CronSchedule> {\n    let trimmed = expr.trim();\n    let normalized = match trimmed.split_whitespace().count() {\n        5 => format!(\"0 {trimmed}\"),\n        6 | 7 => trimmed.to_string(),\n        fields => {\n            anyhow::bail!(\n                \"invalid cron expression `{trimmed}`: expected 5, 6, or 7 fields but found {fields}\"\n            )\n        }\n    };\n    CronSchedule::from_str(&normalized)\n        .with_context(|| format!(\"invalid cron expression `{trimmed}`\"))\n}\n\nfn next_schedule_run_at(\n    expr: &str,\n    after: chrono::DateTime<chrono::Utc>,\n) -> Result<chrono::DateTime<chrono::Utc>> {\n    parse_cron_schedule(expr)?\n        .after(&after)\n        .next()\n        .map(|value| value.with_timezone(&chrono::Utc))\n        .ok_or_else(|| anyhow::anyhow!(\"cron expression `{expr}` did not yield a future run time\"))\n}","sourceCodeStart":2347,"sourceCodeEnd":2383,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/session/manager.rs#L2347-L2383","documentation":"parse_cron_schedule validates cron expressions by counting whitespace-separated fields. Standard cron has 5 fields; this parser accepts 5 (prepends a seconds field), 6, or 7. Any other field count is rejected with this message before CronSchedule::from_str is attempted, giving a clearer diagnostic.","triggerScenarios":"Calling schedule creation (which calls parse_cron_schedule) with a string like 'every day' (0 fields), '* * *' (3 fields), or a miscounted expression whose whitespace-separated token count is not 5, 6, or 7.","commonSituations":"Users pasting natural language ('every morning') instead of cron syntax; forgetting a field ('* * *' instead of '* * * * *'); using descriptors like '@daily' or '@hourly' that split to one token; extra spaces causing miscounts or copy/paste errors.","solutions":["Provide a valid 5-field cron expression, e.g. '0 9 * * *' for daily at 9am","Count the fields: minute hour day-of-month month day-of-week (a 6th seconds field or 7th year field is allowed)","Replace @daily/@hourly descriptors with equivalent explicit cron expressions","Trim stray whitespace and avoid natural-language schedule strings"],"exampleFix":"// before\nparse_cron_schedule(\"every day at 9\")?;\n// after\nparse_cron_schedule(\"0 9 * * *\")?; // 5 fields: daily at 09:00","handlingStrategy":"validation","validationCode":"fn is_valid_cron(expr: &str) -> bool {\n    let n = expr.trim().split_whitespace().count();\n    (5..=7).contains(&n) && !expr.trim().starts_with('@')\n}","typeGuard":null,"tryCatchPattern":"match parse_cron_schedule(input) {\n    Err(e) if e.to_string().contains(\"expected 5, 6, or 7 fields\") => {\n        eprintln!(\"'{input}' is not valid cron; use 5 space-separated fields like '0 9 * * *'\");\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["Validate cron input in the UI with a field counter before submission","Disallow natural-language and @descriptor schedules","Use a cron-construction widget rather than free-text entry"],"tags":["cron","schedule","validation","format"],"backgroundTag":"invalid-argument-format","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}