gitbutlerapp/gitbutler · error · anyhow::Error

GitHub GraphQL enablePullRequestAutoMerge returned an empty

Error message

GitHub GraphQL enablePullRequestAutoMerge returned an empty pull request id

What it means

but-github sent the enablePullRequestAutoMerge GraphQL mutation and GitHub answered, but the pullRequest.id field inside the payload was empty. As the module's own doc-comment explains, GitHub reports a refused mutation as a null field inside `data`, so an empty id means GitHub declined to enable auto-merge - not a transport failure.

Source

Thrown at crates/but-github/src/client.rs:1137

                    input: EnablePullRequestAutoMergeInput {
                        pull_request_id,
                        merge_method: params.merge_method.as_ref().map(Into::into),
                        expected_head_oid: params.expected_head_oid,
                        commit_headline: params.commit_headline,
                        commit_body: params.commit_body,
                        author_email: params.author_email,
                    },
                },
            )
            .await?;

        if data
            .enable_pull_request_auto_merge
            .pull_request
            .id
            .is_empty()
        {
            bail!("GitHub GraphQL enablePullRequestAutoMerge returned an empty pull request id");
        }

        Ok(())
    }

    async fn disable_auto_merge_pull_request(
        &self,
        pull_request_id: &PullRequestNodeId,
    ) -> Result<()> {
        #[derive(Deserialize)]
        struct MutationPayload {
            #[serde(rename = "pullRequest")]
            pull_request: GraphQlPullRequest,
        }

        #[derive(Deserialize)]
        struct GraphQlPullRequest {
            id: String,

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Confirm the PR is open and not a draft before enabling
  2. Enable 'Allow auto-merge' in the repository's Settings -> General -> Pull Requests
  3. Re-authenticate with an account that can write to the repository (`but config forge auth`)
  4. Retry once the PR satisfies its branch-protection rules

Example fix

// before
client.enable_auto_merge_pull_request(&pr_id, &params).await?;

// after
let pr = client.get_pull_request(owner, repo, number).await?;
if pr.state == PrState::Open && !pr.is_draft {
    client.enable_auto_merge_pull_request(&pr_id, &params).await?;
} else {
    anyhow::bail!("skip auto-merge: PR #{number} is not eligible");
}
Defensive patterns

Strategy: validation

Validate before calling

let pr = client.get_pull_request(owner, repo, number).await?;
if pr.state != PrState::Open || pr.is_draft {
    anyhow::bail!("PR #{number} is not eligible for auto-merge");
}
// optionally check repository.autoMergeAllowed via GraphQL before enabling

Type guard

fn ready_for_auto_merge(pr: &PullRequest) -> bool {
    pr.state == PrState::Open && !pr.is_draft && !pr.auto_merge_enabled
}

Try / catch

if let Err(e) = client.enable_auto_merge_pull_request(&pr_id, &params).await {
    if e.to_string().contains("empty pull request id") {
        // GitHub refused the mutation: surface repo-settings hint instead of retrying
        return Err(e.context("auto-merge refused - is 'Allow auto-merge' enabled in repo settings?"));
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Calling enable-auto-merge on a pull request that is not open (draft, merged, closed); on a repo where 'Allow auto-merge' is disabled under Settings -> General -> Pull Requests; with a token lacking write access; or on a PR whose required checks have not been defined/passed so the mutation is refused.

Common situations: Auto-merge never enabled in repo settings; racing another user who merged or closed the PR; fine-grained PATs without Pull requests: write permission; GitHub Enterprise Server versions without auto-merge support.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/d20ece4bc0c13766. Report an issue: GitHub.