gitbutlerapp/gitbutler · error · anyhow::Error
GitHub GraphQL disablePullRequestAutoMerge returned an empty
Error message
GitHub GraphQL disablePullRequestAutoMerge returned an empty pull request id
What it means
The disablePullRequestAutoMerge GraphQL mutation returned but pullRequest.id was empty. As with enable, GitHub nulls the field when the mutation is refused or inapplicable - most commonly because auto-merge is not currently enabled on that PR, so there is nothing to disable.
Source
Thrown at crates/but-github/src/client.rs:1180
}
#[derive(Deserialize)]
struct MutationData {
#[serde(rename = "disablePullRequestAutoMerge")]
disable_pull_request_auto_merge: MutationPayload,
}
let data: MutationData = self
.graphql_query(GQL_DISABLE_PR_AUTO_MERGE, &Variables { pull_request_id })
.await?;
if data
.disable_pull_request_auto_merge
.pull_request
.id
.is_empty()
{
bail!("GitHub GraphQL disablePullRequestAutoMerge returned an empty pull request id");
}
Ok(())
}
async fn get_pull_request_node_id(
&self,
owner: &str,
repo: &str,
pr_number: i64,
) -> Result<PullRequestNodeId> {
#[derive(Serialize)]
struct Variables<'a> {
owner: &'a str,
repo: &'a str,
number: i64,
}
View on GitHub (pinned to caf1f223d3)
Solutions
- Make disable idempotent: fetch the PR first and only call when auto_merge_enabled is true (but-github's PullRequest type already exposes this flag)
- Refresh PR state immediately before disabling
- If GitHub still shows auto-merge but the call fails, verify the token's permissions
Example fix
// before
client.disable_auto_merge_pull_request(&pr_id).await?;
// after
let pr = client.get_pull_request(owner, repo, number).await?;
if pr.auto_merge_enabled {
client.disable_auto_merge_pull_request(&pr_id).await?;
} Defensive patterns
Strategy: validation
Validate before calling
let pr = client.get_pull_request(owner, repo, number).await?;
if !pr.auto_merge_enabled {
// nothing to disable - auto-merge already off
return Ok(());
} Try / catch
if let Err(e) = client.disable_auto_merge_pull_request(&pr_id).await {
if e.to_string().contains("empty pull request id") {
// treat as already-disabled: verify via a fresh GET instead of retrying
return Ok(());
}
return Err(e);
} Prevention
- Treat disable as idempotent: check auto_merge_enabled first
- Refresh PR state right before the call
- Avoid double-submitting UI disable actions
When it happens
Trigger: Calling disable on a PR whose auto-merge was already cancelled (e.g. checks failed and GitHub dropped it), on a closed or merged PR, or with a token that lacks write permission.
Common situations: Client/UI state out of sync with GitHub's auto-merge state; double-running a disable action; acting on stale PR data.
Related errors
- GitHub GraphQL enablePullRequestAutoMerge returned an empty
- GitHub GraphQL pull request #{pr_number} not found for {owne
- GitHub GraphQL pull request #{pr_number} in {owner}/{repo} r
- Could not restore all review targets after the push failed:
- GitHub GraphQL repository not found for {owner}/{repo}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/2fff9ad53b0f8bb2.
Report an issue: GitHub.