gitbutlerapp/gitbutler · error

Provide the replacement content via --file or stdin, or…

Error message

Provide the replacement content via --file or stdin, or take a side with --ours/--theirs/--ai.

What it means

Thrown by apply_resolutions when no replacement content source is available: no --file was given, stdin is a TTY (out.can_prompt()), and no side-taking flag (--ours/--theirs/--ai) was passed. The command cannot know what content to write into the conflicted region.

Solutions

  1. Pass the replacement content with `--file <path>`.
  2. Pipe content via stdin: `echo "..." | but resolve ...`.
  3. Take a side with `--ours`, `--theirs`, or `--ai`.

Example fix

// before
but resolve abc123 src/main.rs
// after
but resolve abc123 src/main.rs --ours
Defensive patterns

Strategy: validation

Validate before calling

function assertContentSource(args: ResolveArgs) {
  if (!args.file && !args.ours && !args.theirs && !args.ai && process.stdin.isTTY) {
    throw new Error('Provide --file, stdin, or --ours/--theirs/--ai');
  }
}

Try / catch

try { await butResolve(commit, path) } catch (e) { if (String(e).includes('Provide the replacement content')) { await butResolve(commit, path, ['--ours']); } }

Prevention

When it happens

Trigger: Running `but resolve <commit> <path>` in an interactive terminal without --file, without piping stdin, and without --ours/--theirs/--ai.

Common situations: Forgetting the content flag when scripting interactively; piping was intended but the command was run in a terminal instead of `... | but resolve ...`.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/85671e143e404217. Report an issue: GitHub.

Appendix: source

Thrown at crates/but/src/command/legacy/resolve.rs:913

        {
            (path, Some(number.parse::<usize>()?))
        }
        _ => (target, None),
    };

    let resolution = if ours {
        HunkResolution::Ours
    } else if theirs {
        HunkResolution::Theirs
    } else if ai {
        HunkResolution::Ai
    } else {
        let content = match &file {
            Some(file) => std::fs::read_to_string(file)
                .with_context(|| format!("Failed to read {}", file.display()))?,
            None => {
                if out.can_prompt() {
                    bail!(
                        "Provide the replacement content via --file or stdin, or take a side with --ours/--theirs/--ai."
                    );
                }
                let mut content = String::new();
                std::io::Read::read_to_string(&mut read, &mut content)?;
                if content.is_empty() {
                    bail!(
                        "stdin was empty. To intentionally delete the conflicted region, pass --file with an empty file."
                    );
                }
                content
            }
        };
        HunkResolution::Content(content)
    };

    // Expand a bare path into explicit per-hunk specs; an explicit `:<N>`
    // target needs no lookup, the API validates it.

View on GitHub (pinned to 58e5313667)