Hmbown/CodeWhale · error · anyhow::Error

Automation prompt is required

Error message

Automation prompt is required

What it means

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.

Solutions

  1. Supply the prompt text the automation should run before saving.
  2. Block form submission while the prompt is blank and show a required-field hint.
  3. For programmatically built automations, assert the prompt is populated before calling the create API.

Example fix

// before
create_automation(name, "   ")?;
// after
anyhow::ensure!(!prompt.trim().is_empty(), "Automation prompt is required");
create_automation(name, prompt)?;
Defensive patterns

Strategy: validation

Validate before calling

if prompt.trim().is_empty() {
    return Err(anyhow!("Automation prompt is required"));
}

Try / catch

match create_automation(&name, &prompt) {
    Ok(rec) => show(rec),
    Err(e) if e.to_string().contains("prompt is required") => focus_prompt_field_with_error(),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Creating or updating an automation with prompt = "" or only whitespace — e.g. a template where the prompt placeholder was never replaced.

Common situations: 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.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/fbf4ea0f14791e5f. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/automation_manager.rs:2790

}

fn ensure_safe_storage_id(kind: &str, value: &str) -> Result<()> {
    let mut components = Path::new(value).components();
    let Some(component) = components.next() else {
        bail!("{kind} must not be empty");
    };
    if components.next().is_some() || !matches!(component, std::path::Component::Normal(_)) {
        bail!("{kind} must be a single path component");
    }
    Ok(())
}

fn validate_name_and_prompt(name: &str, prompt: &str) -> Result<()> {
    if name.trim().is_empty() {
        bail!("Automation name is required");
    }
    if prompt.trim().is_empty() {
        bail!("Automation prompt is required");
    }
    Ok(())
}

fn normalize_optional_string(value: Option<String>) -> Option<String> {
    value
        .map(|value| value.trim().to_string())
        .filter(|value| !value.is_empty())
}

fn write_json_atomic<T: Serialize>(path: &Path, value: &T) -> Result<()> {
    if let Some(parent) = path.parent() {
        fs::create_dir_all(parent).with_context(|| format!("create {}", parent.display()))?;
    }
    crate::utils::write_atomic(path, &serde_json::to_vec_pretty(value)?)
        .with_context(|| format!("write {}", path.display()))
}

View on GitHub (pinned to 73e0f67d83)