{"record":{"id":"fbf4ea0f14791e5f","repo":"Hmbown/CodeWhale","slug":"automation-prompt-is-required","errorCode":null,"errorMessage":"Automation prompt is required","messagePattern":"Automation prompt is required","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/automation_manager.rs","lineNumber":2790,"sourceCode":"}\n\nfn ensure_safe_storage_id(kind: &str, value: &str) -> Result<()> {\n    let mut components = Path::new(value).components();\n    let Some(component) = components.next() else {\n        bail!(\"{kind} must not be empty\");\n    };\n    if components.next().is_some() || !matches!(component, std::path::Component::Normal(_)) {\n        bail!(\"{kind} must be a single path component\");\n    }\n    Ok(())\n}\n\nfn validate_name_and_prompt(name: &str, prompt: &str) -> Result<()> {\n    if name.trim().is_empty() {\n        bail!(\"Automation name is required\");\n    }\n    if prompt.trim().is_empty() {\n        bail!(\"Automation prompt is required\");\n    }\n    Ok(())\n}\n\nfn normalize_optional_string(value: Option<String>) -> Option<String> {\n    value\n        .map(|value| value.trim().to_string())\n        .filter(|value| !value.is_empty())\n}\n\nfn write_json_atomic<T: Serialize>(path: &Path, value: &T) -> Result<()> {\n    if let Some(parent) = path.parent() {\n        fs::create_dir_all(parent).with_context(|| format!(\"create {}\", parent.display()))?;\n    }\n    crate::utils::write_atomic(path, &serde_json::to_vec_pretty(value)?)\n        .with_context(|| format!(\"write {}\", path.display()))\n}\n","sourceCodeStart":2772,"sourceCodeEnd":2808,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/automation_manager.rs#L2772-L2808","documentation":"validate_name_and_prompt, the create/update-path validation helper, rejects an empty or whitespace-only prompt: automations must be created with an actual prompt. This is the generic guard variant of the empty-prompt check, with the offending prompt text as the input at fault.","triggerScenarios":"Creating or updating an automation with prompt = \"\" or only whitespace — e.g. a template where the prompt placeholder was never replaced.","commonSituations":"Submitting the automation form with the prompt box empty; programmatic automation creation where the prompt string was mis-bound; clearing the prompt in an edit and saving.","solutions":["Supply the prompt text the automation should run before saving.","Block form submission while the prompt is blank and show a required-field hint.","For programmatically built automations, assert the prompt is populated before calling the create API."],"exampleFix":"// before\ncreate_automation(name, \"   \")?;\n// after\nanyhow::ensure!(!prompt.trim().is_empty(), \"Automation prompt is required\");\ncreate_automation(name, prompt)?;","handlingStrategy":"validation","validationCode":"if prompt.trim().is_empty() {\n    return Err(anyhow!(\"Automation prompt is required\"));\n}","typeGuard":null,"tryCatchPattern":"match create_automation(&name, &prompt) {\n    Ok(rec) => show(rec),\n    Err(e) if e.to_string().contains(\"prompt is required\") => focus_prompt_field_with_error(),\n    Err(e) => return Err(e),\n}","preventionTips":["Mark the prompt field required and block submission while blank.","Verify template substitution actually filled the prompt before saving.","Confirm edits that clear the prompt instead of silently saving empty values."],"tags":["validation","automation","input"],"backgroundTag":"empty-required-field","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"}