xai-org/grok-build · error
working tree is not clean; commit before merging to '{target
Error message
working tree is not clean; commit before merging to '{target_branch}' What it means
The merge_to_main flow requires a clean working tree before it merges the session branch into the target branch. Before merging it runs `git status --porcelain` and, if any output is present (uncommitted or untracked changes), fails with this error so the merge is never performed on a dirty tree.
Source
Thrown at crates/codegen/xai-grok-workspace/src/session/git.rs:3242
}
/// `MergeToMain` (`workspace.git_merge_to_main`): merge the conversation branch
/// into its target. Merge, never rebase; never force. On conflicts the merge
/// is aborted and HEAD is restored to `conv_branch` (never leave `MERGE_HEAD`
/// on the integration branch).
///
/// Fetch `origin/<target>` *before* checkout, then fast-forward the local
/// target so the deployed SHA can never be behind the durable remote tip; a
/// target that has *diverged* from origin is an error (never a force).
pub async fn merge_to_main(
git_root: &Path,
conv_branch: &str,
target_branch: &str,
push: bool,
) -> Result<GitMergeToMainResult> {
ensure_ref_arg_safe(conv_branch, "session_branch")?;
ensure_ref_arg_safe(target_branch, "target_branch")?;
let dirty = git_cli(git_root, &["status", "--porcelain"]).await?;
anyhow::ensure!(
dirty.is_empty(),
"working tree is not clean; commit before merging to '{target_branch}'"
);
let (fetched, _) = git_cli_raw(
git_root,
&["fetch", "origin", "--end-of-options", target_branch],
)
.await?;
checkout_branch(git_root, target_branch, false).await?;
if fetched
&& !git_cli_raw(
git_root,
&["merge-base", "--is-ancestor", "FETCH_HEAD", "HEAD"],
)
.await?
.0
{
let (ff, ff_out) = git_cli_raw(git_root, &["merge", "--ff-only", "FETCH_HEAD"]).await?;View on GitHub (pinned to bc7f02eddd)
Solutions
- Commit or stash all changes in the working tree (git add -A && git commit, or git stash), then re-run the operation.
- Remove or gitignore untracked build/generated artifacts so `git status --porcelain` is empty.
- If the changes belong to the session, commit them on the session branch first — that is what the flow expects.
- Run git status --porcelain yourself beforehand and surface a friendly prompt to the user to commit.
Example fix
// before
git_ops.merge_to_main(&root, "session/abc", "main", false).await?; // fails if dirty
// after
let dirty = Command::new("git").args(["status", "--porcelain"]).output()?;
if !dirty.stdout.is_empty() {
Command::new("git").args(["add", "-A"]).status()?;
Command::new("git").args(["commit", "-m", "session work"]).status()?;
}
git_ops.merge_to_main(&root, "session/abc", "main", false).await?; Defensive patterns
Strategy: try-catch
Validate before calling
let status = Command::new("git").args(["status", "--porcelain"]).current_dir(&root).output()?;
anyhow::ensure!(status.stdout.is_empty(), "commit or stash changes before merging"); Try / catch
match git_ops.merge_to_main(&root, &branch, "main", false).await {
Err(e) if e.to_string().contains("working tree is not clean") => {
// prompt user to commit/stash, then retry once
prompt_commit_and_retry()?;
}
other => other?,
} Prevention
- Run git status --porcelain before triggering merges and surface a friendly prompt.
- Commit session work on the session branch as part of the workflow, not at merge time.
- Add .gitignore entries for generated artifacts so the tree stays clean.
- Snapshot or stash automatically before starting long-running sessions.
When it happens
Trigger: Calling the merge-to-target operation (crates/codegen/xai-grok-workspace/src/session/git.rs:3242) while the git_root worktree has modified tracked files, staged-but-uncommitted changes, or untracked files — anything `git status --porcelain` reports.
Common situations: An agent/session left generated files or edits in the workspace without committing; the developer forgot to commit before triggering the merge; a tool (formatter, codegen step) wrote files into the repo between the last commit and the merge; .gitignore is missing so build artifacts show as untracked.
Related errors
- workspace is on '{current}', expected '{expected}'
- a merge is already in progress; resolve it or call again wit
- working tree is not clean; commit or discard changes before
- git reset --hard {} failed: {}
- git clean {} failed: {}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/4bcb9fccdf997dbd.
Report an issue: GitHub.