github/github-mcp-server · error

mutation_unconfirmed

mutation_unconfirmed

Error message

mutation response did not include every item

What it means

Raised by executeBatchWrites (pkg/github/projects_batch.go:305) when an aliased GraphQL mutation chunk returns with no transport or GraphQL errors, but fewer populated aliases than items sent in the chunk. The library cannot confirm which writes landed, so it marks every unconfirmed item (this chunk and all later ones) as status 'unknown' with code 'mutation_unconfirmed' and stops. Because field updates are idempotent, the correct response is to read back current values and re-run the affected items.

Source

Thrown at pkg/github/projects_batch.go:306

						FullDatabaseID: oc.FullDatabaseID,
						ItemID:         chunk[i].fullDatabaseID,
					},
				}
			}
		}

		if isGraphQLResponseError(mutateErr) {
			markUnpopulatedUnknown(chunk, outcomes, results, mutateErr)
			continue
		}

		if mutateErr != nil {
			markChunkUnknown(items[start:], results, mutateErr)
			return
		}

		if populated != len(chunk) {
			markChunkUnknown(items[start:], results, fmt.Errorf("mutation response did not include every item"))
			return
		}
	}
}

func markUnpopulatedUnknown(chunk []resolvedBatchItem, outcomes []mutationAliasOutcome, results []batchItemResult, err error) {
	for i, oc := range outcomes {
		if oc.Populated {
			continue
		}
		results[chunk[i].index] = batchItemResult{
			Index:  chunk[i].index,
			Status: batchItemUnknown,
			Ref:    chunk[i].ref,
			Error:  &batchItemError{Code: "mutation_unconfirmed", Message: err.Error()},
		}
	}
}

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Read the tool result JSON: items with results[].status == "unknown" and error.code == "mutation_unconfirmed" are unconfirmed, not failed — do not assume they failed
  2. Fetch the project items (e.g. get_project_items / list project field values) and compare current field values against the intended ones
  3. Re-run update_project_items for only the items whose current value still differs; UpdateProjectV2ItemFieldValue is idempotent
  4. If it recurs consistently, capture the GitHub request ID and check the GitHub status page; a repeatable truncation on the same payload is an API-side issue

Example fix

// result of update_project_items
// before (misread):
//   "unknown": 37  -> assume 37 items failed, re-add all blindly
// after:
//   unknown items -> read back current field values,
//   re-send only those still holding the old value (idempotent update)
Defensive patterns

Strategy: retry

Try / catch

// After the tool call, inspect the result envelope:
// if body.unknown > 0, treat results[].status == "unknown" as UNCONFIRMED.
// Read back current field values for those items; re-send only the ones
// whose current value != intended value. UpdateProjectV2ItemFieldValue is
// idempotent, so a re-run cannot double-apply. Never map unknown -> failed.

Prevention

When it happens

Trigger: Calling update_project_items with a batch where GitHub returns a truncated/partial response: executeAliasedMutation returns mutateErr == nil but the count of outcomes with Populated == true is less than len(chunk) (batchMutationWireChunkSize items). Also seen when an intermediary (proxy, gateway) truncates a large aliased mutation response body.

Common situations: GitHub API incident or server-side truncation on large batched mutations; HTTP intermediaries clipping oversized GraphQL JSON responses; intermittent 5xx recovered into a 200 with a short body. Rare in normal operation — most partial failures surface as GraphQL response errors instead, which only mark the unpopulated aliases unknown and continue.

Related errors


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/c6cd0ba7a429c0d0. Report an issue: GitHub.