{"record":{"id":"df0fa0d89af974cf","repo":"gitbutlerapp/gitbutler","slug":"line-line-number-pick-requires-exactly-one-comm","errorCode":null,"errorMessage":"line {line_number}: pick requires exactly one commit","messagePattern":"line (.+?): pick requires exactly one commit","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/branch/integrate_branch_upstream/parsing.rs","lineNumber":48,"sourceCode":"        if trimmed.is_empty() || trimmed.starts_with('#') {\n            continue;\n        }\n\n        let (command_part, message_part) = split_message_clause(trimmed)\n            .with_context(|| format!(\"line {line_number}: invalid message clause\"))?;\n        let tokens = command_part.split_whitespace().collect::<Vec<_>>();\n        let Some(command) = tokens.first().copied() else {\n            continue;\n        };\n        let arguments = tokens.get(1..).unwrap_or_default();\n\n        let step = match command {\n            \"pick\" => {\n                if message_part.is_some() {\n                    bail!(\"line {line_number}: pick does not accept a message clause\");\n                }\n                if arguments.len() != 1 {\n                    bail!(\"line {line_number}: pick requires exactly one commit\");\n                }\n                let commit = arguments\n                    .first()\n                    .copied()\n                    .expect(\"validated pick arity above\");\n                InteractiveIntegrationStep::Pick {\n                    commit_id: resolve_commit(commit, &allowed_commits).map_err(|err| {\n                        anyhow::anyhow!(\"line {line_number}: invalid pick commit: {err}\")\n                    })?,\n                }\n            }\n            \"merge\" => {\n                if message_part.is_some() {\n                    bail!(\"line {line_number}: merge does not accept a message clause\");\n                }\n                if arguments.len() != 1 {\n                    bail!(\"line {line_number}: merge requires exactly one commit\");\n                }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-workspace/src/branch/integrate_branch_upstream/parsing.rs#L30-L66","documentation":"Raised by `parse_integration_steps_script` when a `pick` line does not have exactly one argument. Tokens are whitespace-split from the command part (before any `|`), so pick must be `pick <commit-spec>` with exactly one spec.","triggerScenarios":"Lines like `pick` (no commit), `pick 4f2a 991b` (two commits), or `pick <full-sha> extra-text`. Note the legacy git-rebase habit `pick <sha> <commit-subject>` fails here because the subject words count as extra arguments.","commonSituations":"Pasting a git-rebase todo (which appends commit subjects after the SHA) into the integration editor; scripts edited by hand or generated by another tool that emit subjects.","solutions":["Use exactly one commit spec: `pick 4f2a9c1`.","If pasting from `git rebase -i`, strip trailing subject text from each line first.","Use a `squash` line if you actually wanted multiple commits combined."],"exampleFix":"# before\npick 4f2a9c1 add login handler\n\n# after\npick 4f2a9c1","handlingStrategy":"validation","validationCode":"// Strip git-rebase-style subjects before parsing a pasted todo:\nlet cleaned: Vec<String> = script.lines().map(|l| {\n    let mut it = l.split_whitespace();\n    match it.next() {\n        Some(cmd @ (\"pick\" | \"merge\")) => format!(\"{} {}\", cmd, it.next().unwrap_or_default()),\n        _ => l.to_string(),\n    }\n}).collect();","typeGuard":null,"tryCatchPattern":"if let Err(err) = parse_integration_steps_script(&script, &divergence) {\n    // err contains 'line {n}: pick requires exactly one commit'; map line n back to the editor\n}","preventionTips":["Validate the script with parse_integration_steps_script before applying.","When pre-filling the editor, always emit bare `pick <sha>` lines (no commit subjects)."],"tags":["rust","git","but-workspace","integration","todo-script","parsing","arity"],"backgroundTag":"rebase-todo-parse-error","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}