{"record":{"id":"23db4c84a7979605","repo":"gitbutlerapp/gitbutler","slug":"refusing-to-directly-update-target-display-witho","errorCode":null,"errorMessage":"Refusing to directly update {target_display} without confirmation. Re-run with --yes to confirm.","messagePattern":"Refusing to directly update (.+?) without confirmation\\. Re-run with --yes to confirm\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/land/messaging.rs","lineNumber":231,"sourceCode":"            .map(|(name, pr)| format!(\"{name} (PR #{pr})\"))\n            .collect::<Vec<_>>()\n            .join(\", \");\n        format!(\n            \"{action} This closes open pull request(s) {prs}: their remote branches are deleted \\\n             after landing.\"\n        )\n    };\n\n    if let Some(out) = out.for_human() {\n        writeln!(out, \"{}\", theme::get().attention.paint(&warning))?;\n    }\n\n    if yes {\n        return Ok(());\n    }\n\n    let Some(mut inout) = out.prepare_for_terminal_input() else {\n        bail!(\n            \"Refusing to directly update {target_display} without confirmation. Re-run with --yes to confirm.\"\n        );\n    };\n\n    let question = if extras.is_empty() {\n        format!(\"Land {branch_name} directly onto {target_display}?\")\n    } else {\n        format!(\"Land {branch_name} and everything below it directly onto {target_display}?\")\n    };\n    if inout.confirm(question, ConfirmDefault::No)? == Confirm::No {\n        bail!(\"Land cancelled\");\n    }\n\n    Ok(())\n}\n\n/// The open pull-request numbers attached to `branch_name` or any of `lower_segments`. Landing\n/// deletes each landed branch's remote copy, which closes the attached reviews on the forge, so","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/land/messaging.rs#L213-L249","documentation":"`but land` updates the target branch directly, so the CLI prints a warning and asks for confirmation (land/messaging.rs). If the output channel cannot host an interactive prompt — `prepare_for_terminal_input()` returns None under pipes, redirects, or CI — it refuses to run the destructive update without explicit consent and tells you to re-run with `--yes`.","triggerScenarios":"Running `but land <branch>` with stdout/stdin not a usable terminal — scripts, CI pipelines, `but land ... | tee`, cron jobs, non-tty ssh — without `--yes`.","commonSituations":"Automation that assumed the prompt would auto-accept; piping land output through another command for logging; CI jobs that interact only via captured output.","solutions":["Re-run with `--yes` once you accept the warning that was printed.","Run in a real terminal (unpiped) to answer the prompt interactively.","In scripts, surface the printed warning to a human first, then run the `--yes` invocation."],"exampleFix":"# before\nbut land my-feature | tee land.log   # piped output -> refuses without confirmation\n\n# after\nbut land my-feature --yes | tee land.log","handlingStrategy":"validation","validationCode":"# Detect non-interactive contexts and pass --yes deliberately\nif ! [ -t 0 ] || ! [ -t 1 ]; then\n  but land \"$branch\" --yes\nelse\n  but land \"$branch\"\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass `--yes` for `but land` in scripts and CI.","Do not pipe land output when you want the interactive prompt.","Read the printed warning (direct target-branch update) before approving the `--yes` run."],"tags":["cli","confirmation","non-interactive","land","gitbutler"],"backgroundTag":"non-interactive-confirmation-required","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}