sigoden/aichat · error

No input

Error message

No input

What it means

`create_input` produced an `Input` that `is_empty()` — no text, file contents, or other source contributed anything — so there is nothing to send to the model. The library bails early rather than issuing an empty request.

Solutions

  1. Provide non-empty prompt text or a non-empty input file
  2. Verify the file passed to -f has content
  3. Check shell variables/streams feeding the prompt for emptiness

Example fix

// before
mytool "$MSG"   # MSG is empty
// after
[ -n "$MSG" ] && mytool "$MSG" || echo "MSG is empty"
Defensive patterns

Strategy: validation

Validate before calling

if text.trim().is_empty()
    && std::fs::metadata(&file_path).map(|m| m.len() == 0).unwrap_or(true)
{
    eprintln!("no input: prompt and file are both empty");
}

Try / catch

match create_input(...).await {
    Err(e) if e.to_string() == "No input" => {
        eprintln!("Nothing to send: check prompt text and -f file contents");
    }
    other => other?,
}

Prevention

When it happens

Trigger: No prompt argument given, `-f/--file` points to an empty file, or all input sources resolve to empty when `create_input` is called by `run`.

Common situations: Empty or whitespace-only prompt; the file passed with -f is empty; shell variable interpolation produced an empty string (`mytool "$EMPTY_VAR"`).

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 sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/1828ed3bda84f04e. Report an issue: GitHub.

Appendix: source

Thrown at src/main.rs:347

    config: &GlobalConfig,
    text: Option<String>,
    file: &[String],
    abort_signal: AbortSignal,
) -> Result<Input> {
    let input = if file.is_empty() {
        Input::from_str(config, &text.unwrap_or_default(), None)
    } else {
        Input::from_files_with_spinner(
            config,
            &text.unwrap_or_default(),
            file.to_vec(),
            None,
            abort_signal,
        )
        .await?
    };
    if input.is_empty() {
        bail!("No input");
    }
    Ok(input)
}

fn setup_logger(is_serve: bool) -> Result<()> {
    let (log_level, log_path) = Config::log_config(is_serve)?;
    if log_level == LevelFilter::Off {
        return Ok(());
    }
    let crate_name = env!("CARGO_CRATE_NAME");
    let log_filter = match std::env::var(get_env_name("log_filter")) {
        Ok(v) => v,
        Err(_) => match is_serve {
            true => format!("{crate_name}::serve"),
            false => crate_name.into(),
        },
    };
    let config = ConfigBuilder::new()

View on GitHub (pinned to 82976d349a)