{"record":{"id":"e370f5ea2e502eb8","repo":"Hmbown/CodeWhale","slug":"automation-prompt-cannot-be-empty","errorCode":null,"errorMessage":"Automation prompt cannot be empty","messagePattern":"Automation prompt cannot be empty","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/automation_manager.rs","lineNumber":1051,"sourceCode":"        Ok(out)\n    }\n\n    pub fn update_automation(\n        &self,\n        id: &str,\n        req: UpdateAutomationRequest,\n    ) -> Result<AutomationRecord> {\n        let mut existing = self.get_automation(id)?;\n\n        if let Some(name) = req.name {\n            if name.trim().is_empty() {\n                bail!(\"Automation name cannot be empty\");\n            }\n            existing.name = name.trim().to_string();\n        }\n        if let Some(prompt) = req.prompt {\n            if prompt.trim().is_empty() {\n                bail!(\"Automation prompt cannot be empty\");\n            }\n            existing.prompt = prompt.trim().to_string();\n        }\n        if let Some(rrule) = req.rrule {\n            let normalized = rrule.trim().to_ascii_uppercase();\n            AutomationSchedule::parse_rrule(&normalized)?;\n            existing.rrule = normalized;\n            if matches!(existing.status, AutomationStatus::Active) {\n                let schedule = AutomationSchedule::parse_rrule(&existing.rrule)?;\n                existing.next_run_at =\n                    Some(schedule.next_after_with_anchor(Utc::now(), existing.created_at)?);\n            }\n        }\n        if let Some(cwds) = req.cwds {\n            existing.cwds = cwds;\n        }\n        if let Some(mode) = req.mode {\n            existing.mode = normalize_optional_string(Some(mode));","sourceCodeStart":1033,"sourceCodeEnd":1069,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/automation_manager.rs#L1033-L1069","documentation":"update_automation rejects a prompt update whose value trims to empty. Only Some(prompt) triggers validation; omitting the field leaves the prompt unchanged. The trimmed value is persisted and later executed.","triggerScenarios":"Calling update_automation with UpdateAutomationRequest { prompt: Some(String::new()), .. } or Some(\"\\t\".into()).","commonSituations":"Template-rendered prompts whose variables resolve to whitespace; UIs submitting unvalidated textarea content; scripts defaulting to empty strings.","solutions":["Send a non-empty prompt, or omit the field to keep the current prompt","Validate trim-ness before submitting the update","Default templates to a descriptive fallback string"],"exampleFix":"// before\nlet req = UpdateAutomationRequest { prompt: Some(\"  \".to_string()), ..Default::default() };\n\n// after\nlet req = UpdateAutomationRequest { prompt: Some(\"Summarize today's incidents\".to_string()), ..Default::default() };","handlingStrategy":"validation","validationCode":"fn prompt_update_ok(prompt: &Option<String>) -> bool {\n    prompt.as_deref().is_none_or(|p| !p.trim().is_empty())\n}","typeGuard":"fn is_non_blank(s: &str) -> bool { !s.trim().is_empty() }","tryCatchPattern":null,"preventionTips":["Require visible text for prompts in the UI before enabling submit","Omit the prompt field instead of sending an empty string for no-change","Give templates a descriptive fallback so rendered prompts are never blank"],"tags":["rust","validation","empty-string","automation"],"backgroundTag":"required-field-empty","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}