{"record":{"id":"26d1205fe7dbdbfd","repo":"Hmbown/CodeWhale","slug":"invalid-byday-value-other","errorCode":null,"errorMessage":"Invalid BYDAY value '{other}'","messagePattern":"Invalid BYDAY value '(.+?)'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/automation_manager.rs","lineNumber":689,"sourceCode":"fn resolve_local_datetime<Tz: TimeZone>(\n    timezone: &Tz,\n    naive: NaiveDateTime,\n) -> Option<DateTime<Tz>> {\n    timezone.from_local_datetime(&naive).earliest()\n}\n\nfn parse_byday(value: &str) -> Result<Vec<Weekday>> {\n    let mut days = Vec::new();\n    for token in value.split(',') {\n        let day = match token.trim().to_ascii_uppercase().as_str() {\n            \"MO\" => Weekday::Mon,\n            \"TU\" => Weekday::Tue,\n            \"WE\" => Weekday::Wed,\n            \"TH\" => Weekday::Thu,\n            \"FR\" => Weekday::Fri,\n            \"SA\" => Weekday::Sat,\n            \"SU\" => Weekday::Sun,\n            other => bail!(\"Invalid BYDAY value '{other}'\"),\n        };\n        if !days.contains(&day) {\n            days.push(day);\n        }\n    }\n    Ok(days)\n}\n\nfn parse_once_schedule(parts: &BTreeMap<String, String>) -> Result<AutomationSchedule> {\n    for key in parts.keys() {\n        if key != \"FREQ\" && key != \"AT\" {\n            bail!(\"Unsupported RRULE field '{key}' for ONCE. Allowed: FREQ,AT\");\n        }\n    }\n    let raw_at = parts\n        .get(\"AT\")\n        .ok_or_else(|| anyhow::anyhow!(\"ONCE schedules require AT\"))?;\n    let at = parse_once_at(raw_at)?;","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/automation_manager.rs#L671-L707","documentation":"parse_byday validates each comma-separated BYDAY token against the two-letter weekday names MO..SU. Any token that is not one of the seven recognized codes (after trim and ASCII uppercase) bails with this message naming the offending value. This runs while parsing an RRULE into an AutomationSchedule, so it fires at schedule-creation time, not at run time.","triggerScenarios":"Calling AutomationSchedule::parse with FREQ=WEEKLY (or HOURLY) whose BYDAY contains tokens other than MO,TU,WE,TH,FR,SA,SU — e.g. full names (MONDAY), numeric prefixes (1MO, RRULE ordinals), or stray characters.","commonSituations":"Users copying standard iCalendar RRULEs that allow ordinal prefixes like 2MO (not supported here); writing MON instead of MO; leaving trailing punctuation or localized weekday abbreviations.","solutions":["Use only the two-letter codes MO,TU,WE,TH,FR,SA,SU separated by commas.","Strip numeric ordinal prefixes (2MO → MO); ordinal repetition is not supported.","Trim whitespace/localized names and re-save the schedule."],"exampleFix":"// before\nFREQ=WEEKLY;BYDAY=1MO,FR\n// after\nFREQ=WEEKLY;BYDAY=MO,FR","handlingStrategy":"validation","validationCode":"const BYDAY_CODES: [&str; 7] = [\"MO\",\"TU\",\"WE\",\"TH\",\"FR\",\"SA\",\"SU\"];\nfn valid_byday(v: &str) -> bool {\n    v.split(',').all(|t| BYDAY_CODES.contains(&t.trim().to_ascii_uppercase().as_str()))\n}","typeGuard":null,"tryCatchPattern":"match AutomationSchedule::parse(rrule) {\n    Ok(s) => save(s),\n    Err(e) if e.to_string().contains(\"Invalid BYDAY\") => show_day_code_hint(&e),\n    Err(e) => report(e),\n}","preventionTips":["Offer a weekday picker in the UI so free-text day names never reach the parser.","Strip ordinal prefixes (1MO, 2MO) before saving iCalendar-derived RRULEs.","Normalize case and trim tokens client-side."],"tags":["validation","scheduling","rrule"],"backgroundTag":"invalid-enum-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}