{"record":{"id":"d9828cedaa2cd955","repo":"gitbutlerapp/gitbutler","slug":"github-graphql-convertpullrequesttodraft-returned-an-empty","errorCode":null,"errorMessage":"GitHub GraphQL convertPullRequestToDraft returned an empty pull request id","messagePattern":"GitHub GraphQL convertPullRequestToDraft returned an empty pull request id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-github/src/client.rs","lineNumber":1595,"sourceCode":"            pull_request: GraphQlPullRequest,\n        }\n\n        #[derive(Deserialize)]\n        struct GraphQlPullRequest {\n            id: String,\n        }\n\n        let data: MutationData = self\n            .graphql_query(GQL_SET_PR_DRAFT, &Variables { pull_request_id })\n            .await?;\n\n        if data\n            .convert_pull_request_to_draft\n            .pull_request\n            .id\n            .is_empty()\n        {\n            bail!(\"GitHub GraphQL convertPullRequestToDraft returned an empty pull request id\");\n        }\n\n        Ok(())\n    }\n\n    /// Enable or disable a PR's auto-merge.\n    pub async fn set_pull_request_auto_merge(\n        &self,\n        params: &SetPullRequestAutoMergeParams<'_>,\n    ) -> Result<()> {\n        let pull_request_id = self\n            .get_pull_request_node_id(params.owner, params.repo, params.pr_number)\n            .await?;\n\n        match &params.state {\n            AutoMergeState::Disabled => {\n                self.disable_auto_merge_pull_request(&pull_request_id).await\n            }","sourceCodeStart":1577,"sourceCodeEnd":1613,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-github/src/client.rs#L1577-L1613","documentation":"The convertPullRequestToDraft GraphQL mutation returned successfully but with an empty pull_request.id in the response. The library requires the node id to consider the operation confirmed and bails otherwise.","triggerScenarios":"Calling set_pull_request_to_draft / convert_pull_request_to_draft when the mutation response lacks the PR node id — often because the PR is already a draft (no-op) or the GraphQL response shape is not what the client's query expects.","commonSituations":"Automations converting already-draft PRs; head branches from forks with restricted permissions; GitHub GraphQL schema changes.","solutions":["Skip the call when the PR is already a draft (check state == 'draft' beforehand)","Inspect the raw GraphQL response to confirm whether the id is truly absent","Confirm the authenticated token has write access to the repository","Check the GitHub GraphQL schema/changelog for renames affecting the queried fields"],"exampleFix":"// before\nclient.set_pull_request_draft_state(&params).await?;\n// after\nif pr.is_draft {\n    return Ok(()); // already a draft, nothing to do\n}\nclient.set_pull_request_draft_state(&params).await?;","handlingStrategy":"validation","validationCode":"// skip when already a draft\nif pr.is_draft { return Ok(()); }","typeGuard":null,"tryCatchPattern":"match client.set_pull_request_draft_state(&params).await {\n    Err(e) if e.to_string().contains(\"empty pull request id\") => {\n        // refetch and verify whether the conversion actually happened\n        let pr = client.get_pull_request(owner, repo, pr_number).await?;\n        if pr.is_draft { Ok(()) } else { Err(e) }\n    }\n    other => other,\n}","preventionTips":["Check is_draft before converting","Verify token write access on the target repo/fork","Confirm the mutation payload with gh api graphql on failure","Watch the GitHub GraphQL changelog for schema changes"],"tags":["github","graphql","pull-request","draft"],"backgroundTag":"empty-required-field","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}