gitbutlerapp/gitbutler · error · anyhow::Error
line {line_number}: pick does not accept a message clause
Error message
line {line_number}: pick does not accept a message clause What it means
Raised by `parse_integration_steps_script` (parsing.rs) when a script line starts with `pick` but also contains a `| message=...` clause. Only `squash` accepts a message clause; `pick` has no message of its own. The line number in the message is 1-based within the edited script.
Source
Thrown at crates/but-workspace/src/branch/integrate_branch_upstream/parsing.rs:45
let line_number = line_number + 1;
let line = line.to_str_lossy();
let trimmed = line.trim();
if trimmed.is_empty() || trimmed.starts_with('#') {
continue;
}
let (command_part, message_part) = split_message_clause(trimmed)
.with_context(|| format!("line {line_number}: invalid message clause"))?;
let tokens = command_part.split_whitespace().collect::<Vec<_>>();
let Some(command) = tokens.first().copied() else {
continue;
};
let arguments = tokens.get(1..).unwrap_or_default();
let step = match command {
"pick" => {
if message_part.is_some() {
bail!("line {line_number}: pick does not accept a message clause");
}
if arguments.len() != 1 {
bail!("line {line_number}: pick requires exactly one commit");
}
let commit = arguments
.first()
.copied()
.expect("validated pick arity above");
InteractiveIntegrationStep::Pick {
commit_id: resolve_commit(commit, &allowed_commits).map_err(|err| {
anyhow::anyhow!("line {line_number}: invalid pick commit: {err}")
})?,
}
}
"merge" => {
if message_part.is_some() {
bail!("line {line_number}: merge does not accept a message clause");
}View on GitHub (pinned to caf1f223d3)
Solutions
- Remove the `| message=...` clause from the pick line: `pick 4f2a9c1`.
- If you want pick + different message, use a `squash` step with a single intent or adjust the plan upstream — the grammar only supports messages on squash.
- Check the script against `render_integration_steps_script` output for the canonical format before submitting.
Example fix
# before pick 4f2a9c1 | message="new message" # after pick 4f2a9c1
Defensive patterns
Strategy: validation
Validate before calling
// Dry-run the script through the parser before applying:
let steps = but_workspace::branch::integrate_branch_upstream::parse_integration_steps_script(&script, &divergence)
.map_err(|e| user_friendly(e))?; // surfaces 'line N: pick does not accept a message clause' Try / catch
match parse_integration_steps_script(&script, &divergence) {
Ok(steps) => { /* proceed to integrate_branch_with_steps */ }
Err(err) => show_editor_error(err.to_string()), // errors carry 'line N:' context already
} Prevention
- Always parse/validate the edited script before integration; the parse errors include line numbers, ideal for editor highlighting.
- Generate the editable script with render_integration_steps_script so users start from valid syntax.
- Document the grammar in the editor UI: only squash accepts `| message="..."`.
When it happens
Trigger: Script line like `pick 4f2a9c1 | message="fix"` — `split_message_clause` splits on the first `|`, so pick sees a Some(message_part) and bails. Any attempt to reword while picking hits this.
Common situations: Users familiar with git rebase's `reword`/`pick <sha> <subject>` syntax try to attach a message to pick; or a UI round-trips a squash line into a pick line but keeps the message clause.
Related errors
- line {line_number}: pick requires exactly one commit
- line {line_number}: merge does not accept a message clause
- line {line_number}: merge requires exactly one commit
- line {line_number}: squash requires at least two commits
- line {line_number}: unknown command '{other}'
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/4b62399d329db3b2.
Report an issue: GitHub.