{"record":{"id":"2fff9ad53b0f8bb2","repo":"gitbutlerapp/gitbutler","slug":"github-graphql-disablepullrequestautomerge-returne","errorCode":null,"errorMessage":"GitHub GraphQL disablePullRequestAutoMerge returned an empty pull request id","messagePattern":"GitHub GraphQL disablePullRequestAutoMerge returned an empty pull request id","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-github/src/client.rs","lineNumber":1180,"sourceCode":"        }\n\n        #[derive(Deserialize)]\n        struct MutationData {\n            #[serde(rename = \"disablePullRequestAutoMerge\")]\n            disable_pull_request_auto_merge: MutationPayload,\n        }\n\n        let data: MutationData = self\n            .graphql_query(GQL_DISABLE_PR_AUTO_MERGE, &Variables { pull_request_id })\n            .await?;\n\n        if data\n            .disable_pull_request_auto_merge\n            .pull_request\n            .id\n            .is_empty()\n        {\n            bail!(\"GitHub GraphQL disablePullRequestAutoMerge returned an empty pull request id\");\n        }\n\n        Ok(())\n    }\n\n    async fn get_pull_request_node_id(\n        &self,\n        owner: &str,\n        repo: &str,\n        pr_number: i64,\n    ) -> Result<PullRequestNodeId> {\n        #[derive(Serialize)]\n        struct Variables<'a> {\n            owner: &'a str,\n            repo: &'a str,\n            number: i64,\n        }\n","sourceCodeStart":1162,"sourceCodeEnd":1198,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-github/src/client.rs#L1162-L1198","documentation":"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.","triggerScenarios":"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.","commonSituations":"Client/UI state out of sync with GitHub's auto-merge state; double-running a disable action; acting on stale PR data.","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"],"exampleFix":"// before\nclient.disable_auto_merge_pull_request(&pr_id).await?;\n\n// after\nlet pr = client.get_pull_request(owner, repo, number).await?;\nif pr.auto_merge_enabled {\n    client.disable_auto_merge_pull_request(&pr_id).await?;\n}","handlingStrategy":"validation","validationCode":"let pr = client.get_pull_request(owner, repo, number).await?;\nif !pr.auto_merge_enabled {\n    // nothing to disable - auto-merge already off\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = client.disable_auto_merge_pull_request(&pr_id).await {\n    if e.to_string().contains(\"empty pull request id\") {\n        // treat as already-disabled: verify via a fresh GET instead of retrying\n        return Ok(());\n    }\n    return Err(e);\n}","preventionTips":["Treat disable as idempotent: check auto_merge_enabled first","Refresh PR state right before the call","Avoid double-submitting UI disable actions"],"tags":["github","graphql","pull-request","auto-merge"],"backgroundTag":"graphql-null-response-field","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}