Hmbown/CodeWhale · error · anyhow::Error

Automation name is required

Error message

Automation name is required

What it means

validate_name_and_prompt requires a non-blank automation name before an automation record can be created or saved. A name that is empty or only whitespace is rejected because the name is user-facing and used to identify the automation.

Solutions

  1. Provide a non-empty, non-whitespace name when creating/updating the automation.
  2. Add a required-field check in the UI/form so submission is blocked while name is blank.
  3. If the name is derived from other input, fall back to a default name when it trims to empty.

Example fix

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

Strategy: validation

Validate before calling

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

Try / catch

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

Prevention

When it happens

Trigger: Creating or updating an automation via the API/UI with name set to "" or whitespace (e.g. " ").

Common situations: A form submitted without filling the name field; trimming/pasting that left only spaces; programmatic creation where the name variable was never assigned.

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/42c9a881a9ab4c29. Report an issue: GitHub.

Appendix: source

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

        );
    }
    Ok(run)
}

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)?)

View on GitHub (pinned to 73e0f67d83)