screenpipe/screenpipe · error
proposal confirmation requires an interactive terminal; revi
Error message
proposal confirmation requires an interactive terminal; review the preview and rerun with --yes
What it means
confirm_proposal is the safety gate before submitting a team skill bundle for review. When the operator did not pass --yes, it requires an interactive terminal to show a y/N prompt; if stdin is not a TTY (piped input, CI, scripts) it refuses to guess and bails, telling the user to review the preview and rerun with --yes.
Source
Thrown at crates/screenpipe-engine/src/cli/team_skills.rs:409
bundle.files.len(),
bundle.total_bytes,
bundle.discovery_chars,
bundle.activation_chars,
bundle.has_scripts
);
println!("digest: {}", bundle.digest);
for (path, content) in &bundle.files {
println!(" {:<48} {:>8} B", path, content.len());
}
println!("\nThis creates a private proposal only. Admin review is required.");
}
fn confirm_proposal(yes: bool) -> anyhow::Result<bool> {
if yes {
return Ok(true);
}
if !io::stdin().is_terminal() {
anyhow::bail!(
"proposal confirmation requires an interactive terminal; review the preview and rerun with --yes"
);
}
print!("Submit this exact bundle for review? [y/N] ");
io::stdout().flush()?;
let mut answer = String::new();
io::stdin().read_line(&mut answer)?;
Ok(matches!(
answer.trim().to_ascii_lowercase().as_str(),
"y" | "yes"
))
}
async fn send_json(builder: reqwest::RequestBuilder, token: &str) -> anyhow::Result<Value> {
let response = builder.bearer_auth(token).send().await?;
let status = response.status();
let body = response.json::<Value>().await.unwrap_or(Value::Null);
if !status.is_success() {View on GitHub (pinned to 4ebf712990)
Solutions
- Run the command once to see the preview, verify the bundle, then rerun with `--yes` to skip the prompt
- If running in CI/scripting, add `--yes` to the propose command after confirming the preview manually once
- Run the command inside a real interactive TTY if confirmation is desired
Example fix
// before echo y | screenpipe team-skills propose ./my-skill // after screenpipe team-skills propose ./my-skill --preview # review output screenpipe team-skills propose ./my-skill --yes # explicit submit
Defensive patterns
Strategy: validation
Validate before calling
use std::io::IsTerminal;
if !std::io::stdin().is_terminal() && !yes {
anyhow::bail!("add --yes for non-interactive use");
} Try / catch
match propose_skill(args) {
Err(e) if e.to_string().contains("interactive terminal") => {
eprintln!("non-interactive: rerun with --yes after reviewing preview");
}
other => other?,
} Prevention
- Add --yes in scripts/CI after manually reviewing the preview once
- Run interactive confirmations in a real TTY
- Document the --yes requirement in team automation docs
When it happens
Trigger: Calling `screenpipe team-skills propose` without `--yes` in any context where stdin is not a terminal: CI pipelines, `echo y | screenpipe ...`, ssh without a TTY, or piping output through another command.
Common situations: Automation scripts that call the CLI non-interactively; running the command from an IDE terminal wrapper without a TTY; forgetting --yes in a documented CI job; cron/systemd invocations.
Related errors
- skill description must contain 1-1024 characters
- team skill API {}{}: {}
- screenpipe is running on port {port} — stop it first (quit t
- no cloud session found. run `screenpipe login`
- preset '{}' not found
AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01).
Data as JSON: /api/errors/4061494d94915371.
Report an issue: GitHub.