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
- Pass a non-empty --description flag on the command line
- Run the command in a real terminal so the interactive prompt appears
- 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
- Always pass --description in scripts, CI, and containers regardless of TTY
- Detect interactivity early (test -t 0 in shell, IsTerminal in Rust) and branch before invoking the CLI
- Never assume a prompt will appear when the command runs under another process
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
- No input received from stdin
- cli-secret-needs-tty
- no editor found; set VISUAL or EDITOR
- {editor} exited with non-zero status
- No OAuth code provided
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/ff25a974048b92bd.
Report an issue: GitHub.