gitbutlerapp/gitbutler · error

GitHub GraphQL markPullRequestReadyForReview returned an…

Error message

GitHub GraphQL markPullRequestReadyForReview returned an empty pull request id

What it means

The markPullRequestReadyForReview GraphQL mutation succeeded at the HTTP level and returned data, but the pull_request.id in the response was an empty string. The library treats a missing node id as an unusable/protocol-violating response and bails.

Solutions

  1. Check the PR's current state first and skip the mutation if it is already ready for review
  2. Verify the mutation response JSON manually (e.g. with gh api graphql) to confirm GitHub is returning the id
  3. Retry once; if it persists, check GitHub API status/changelog for GraphQL schema changes
  4. Ensure the token can act on this PR (permissions on the fork/repo)

Example fix

// before
client.mark_pull_request_ready_for_review(&params).await?;
// after
if !is_draft(pr) {
    return Ok(()); // already ready, skip mutation
}
client.mark_pull_request_ready_for_review(&params).await?;
Defensive patterns

Strategy: validation

Validate before calling

// skip the mutation when the PR is not a draft
if !pr.is_draft { return Ok(()); }

Try / catch

// treat empty-id as possibly benign (already ready) and refetch state
match client.mark_pull_request_ready_for_review(&params).await {
    Err(e) if e.to_string().contains("empty pull request id") => {
        let pr = client.get_pull_request(owner, repo, pr_number).await?;
        if !pr.is_draft { Ok(()) } else { Err(e) }
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling mark_pull_request_ready_for_review when GitHub's response omits or empties the returned PR node id — typically because the mutation targeted a PR in a state where the mutation no-ops or the payload shape changed (API schema drift).

Common situations: PR is already marked ready for review (mutation returns but id may be empty in edge payloads); PR is actually a draft of a fork where permissions differ; GitHub API schema changes between versions.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/efe57cef08dd6558. Report an issue: GitHub.

Appendix: source

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

            pull_request: GraphQlPullRequest,
        }

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

        let data: MutationData = self
            .graphql_query(GQL_SET_PR_READY_FOR_REVIEW, &Variables { pull_request_id })
            .await?;

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

        Ok(())
    }

    async fn set_pull_request_to_draft(&self, pull_request_id: &PullRequestNodeId) -> Result<()> {
        #[derive(Serialize)]
        #[serde(rename_all = "camelCase")]
        struct Variables<'a> {
            pull_request_id: &'a PullRequestNodeId,
        }

        #[derive(Deserialize)]
        struct MutationData {
            #[serde(rename = "convertPullRequestToDraft")]
            convert_pull_request_to_draft: MutationPayload,
        }

View on GitHub (pinned to 58e5313667)