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
- Check the PR's current state first and skip the mutation if it is already ready for review
- Verify the mutation response JSON manually (e.g. with gh api graphql) to confirm GitHub is returning the id
- Retry once; if it persists, check GitHub API status/changelog for GraphQL schema changes
- Ensure the token can act on this PR (permissions on the fork/repo)
Example fix
// before
client.mark_pull_request_ready_for_review(¶ms).await?;
// after
if !is_draft(pr) {
return Ok(()); // already ready, skip mutation
}
client.mark_pull_request_ready_for_review(¶ms).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(¶ms).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
- Check PR draft state before calling ready-for-review
- Keep the crate updated with GitHub GraphQL schema changes
- Test the raw mutation with gh api graphql when debugging
- Retry idempotent state mutations once before failing
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
- GitHub GraphQL convertPullRequestToDraft returned an empty…
- GitHub GraphQL disablePullRequestAutoMerge returned an…
- GitHub GraphQL enablePullRequestAutoMerge returned an empty…
- GitHub GraphQL pull request
- GitHub GraphQL pull request #
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)