Hmbown/CodeWhale · error · anyhow::Error
CRON field contains an empty list item
Error message
CRON {field_name} field contains an empty list item What it means
Within a comma-separated cron field, empty list items are invalid: each part between commas must contain a value. The parser splits on ',' and bails when any resulting part trims to empty, e.g. '1,,5' or a trailing comma '1,5,'.
Solutions
- Remove the extra/stray comma so every item has a value, e.g. '1,5' instead of '1,,5'
- Build the field by filtering empty entries before joining: parts.iter().filter(|p| !p.is_empty()).join(",")
- Trim the whole field and strip trailing commas before saving
Example fix
// before
let field = format!("{},,{}", a, b); // empty item
// after
let field = [a, b].iter().filter(|v| !v.is_empty()).cloned().collect::<Vec<_>>().join(","); Defensive patterns
Strategy: validation
Validate before calling
fn no_empty_list_items(field: &str) -> bool {
field.split(',').all(|p| !p.trim().is_empty())
} Prevention
- Filter empty entries before joining list values with commas
- Never hand-edit fields by deleting only the value
- Round-trip parse fields before persisting them
When it happens
Trigger: A cron field like 'minutes=1,,5', '*/5, ' or '0,15,30,' — any double comma, leading, or trailing comma in minute/hour/day/month/weekday.
Common situations: Programmatic list building joined with commas where a list element was empty (e.g. vec of Option values stringified); hand-editing a schedule and deleting a value but not its comma.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- CRON EXPR day-of-month/month combination can never occur
- CRON EXPR must have exactly 5 fields: minute hour…
- CRON field must not be empty
- CRON range start must be <= end
- CRON step must be >= 1
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/b0f206273bd0e04a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/automation_manager.rs:829
#[derive(Debug, Clone)]
struct CronField {
values: Vec<u32>,
is_wildcard: bool,
}
impl CronField {
fn parse(raw: &str, min: u32, max: u32, names: CronNameMap, field_name: &str) -> Result<Self> {
let trimmed = raw.trim();
if trimmed.is_empty() {
bail!("CRON {field_name} field must not be empty");
}
let mut values = Vec::new();
let is_wildcard = trimmed == "*";
for part in trimmed.split(',') {
let part = part.trim();
if part.is_empty() {
bail!("CRON {field_name} field contains an empty list item");
}
let (base, step) = if let Some((base, step)) = part.split_once('/') {
let step = step
.trim()
.parse::<u32>()
.with_context(|| format!("Failed to parse CRON {field_name} step"))?;
if step == 0 {
bail!("CRON {field_name} step must be >= 1");
}
(base.trim(), step)
} else {
(part, 1)
};
let range = if base == "*" {
(min, max)
} else if let Some((start, end)) = base.split_once('-') {
let start = parse_cron_atom(start.trim(), min, max, names, field_name)?;View on GitHub (pinned to 73e0f67d83)