zeroclaw-labs/zeroclaw · error · anyhow::Error

--description is required when stdin is not a TTY

Error message

--description is required when stdin is not a TTY

What it means

Thrown by prompt_for_description in the skill-creation CLI flow (src/skills/mod.rs). When no usable --description was given and stdin is not a TTY, the interactive dialoguer prompt cannot be shown, so the command aborts instead of hanging on an invisible prompt. It guarantees scripted or piped invocations always supply an explicit description.

Source

Thrown at src/skills/mod.rs:1227

    Ok(())
}

fn prompt_for_description(description: Option<String>) -> Result<String> {
    if let Some(d) = description
        && !d.trim().is_empty()
    {
        return Ok(d);
    }
    if std::io::IsTerminal::is_terminal(&std::io::stdin()) {
        let prompt: String = dialoguer::Input::new()
            .with_prompt("Skill description (what it does, when to use it)")
            .interact_text()?;
        if prompt.trim().is_empty() {
            anyhow::bail!("description must not be empty");
        }
        Ok(prompt)
    } else {
        anyhow::bail!("--description is required when stdin is not a TTY");
    }
}

fn open_in_editor(path: &std::path::Path) -> Result<()> {
    let Some(editor) = editor_from_env_or_path() else {
        anyhow::bail!("no editor found; set VISUAL or EDITOR");
    };
    let status = std::process::Command::new(&editor).arg(path).status()?;
    if !status.success() {
        anyhow::bail!("{editor} exited with non-zero status");
    }
    Ok(())
}

fn editor_from_env_or_path() -> Option<String> {
    std::env::var("VISUAL")
        .ok()
        .filter(|value| !value.trim().is_empty())

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Pass a non-empty --description flag on the command line
  2. Run the command in a real terminal so the interactive prompt appears
  3. If wrapping the CLI from another program, allocate a PTY (e.g. script -qc, docker run -t) or always supply the flag

Example fix

# before (stdin piped, fails)
echo | zeroclaw skills create deploy-skill
# after
zeroclaw skills create deploy-skill --description "Deploys the web dashboard"
Defensive patterns

Strategy: validation

Validate before calling

# bash wrapper: always supply --description when not interactive
args=("$@")
if ! [ -t 0 ] && [[ " $* " != *" --description"* ]]; then
  args+=(--description "${SKILL_DESCRIPTION:?set SKILL_DESCRIPTION for non-interactive runs}")
fi
zeroclaw skills create "${args[@]}"

Prevention

When it happens

Trigger: Running the skill-create command with stdin piped, redirected, or detached from a terminal (CI job, cron, docker exec without -t, another process spawning the CLI) without passing --description; passing --description with only whitespace while stdin is non-interactive.

Common situations: Automation wrappers and CI pipelines that call the CLI without a PTY; running inside containers or IDE task runners where no TTY is allocated; users piping input expecting it to be read as the description.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/ff25a974048b92bd. Report an issue: GitHub.