dgraph-io/dgraph · error

duplicate XID found: %s

Error message

duplicate XID found: %s

What it means

The same external ID (XID / @id field) value appears more than once within a single mutation request. Dgraph tracks XID occurrences while rewriting the mutation; a duplicate would create or reference the same logical node ambiguously, so it fails with this error. It notes the duplicated XID string.

Source

Thrown at graphql/resolve/mutation_rewriter.go:1893

				// There are two cases:
				// Case 1: We are at top level:
				// 	       We return an error if the same node is referenced twice at top level.
				// Case 2: We are not at top level:
				//         We don't return an error if one of the occurrences of XID is a reference
				//         and other is definition.
				//         We return an error if both occurrences contain values other than XID and are
				//         not equal.
				if xidMetadata.variableObjMap[variable] != nil {
					// if we already encountered an object with same xid earlier, and this object is
					// considered a duplicate of the existing object, then return error.

					if xidMetadata.isDuplicateXid(atTopLevel, variable, obj, srcField) {
						// TODO(Jatin): Add this error for inherited @id field with interface arg.
						//  Currently we don't return this error for the nested case when
						//  at both root and nested level we have same value of @id fields
						//  which have interface arg set and are inherited from same interface
						//  but are in different implementing type, we currently treat that as reference.
						err := errors.Errorf("duplicate XID found: %s", xidString)
						retErrors = append(retErrors, err)
						return nil, nil, retErrors
					}
					// In the other case it is not duplicate, we update variableObjMap in case the new
					// occurrence of XID is its description and the old occurrence was a reference.
					// Example:
					// obj = { "id": "1", "name": "name1"}
					// xidMetadata.variableObjMap[variable] = { "id": "1" }
					// In this case, as obj is the correct definition of the object, we update variableObjMap
					oldObj := xidMetadata.variableObjMap[variable]
					// TODO(Jatin): This condition also needs to change in accordance with multiple xids.
					//  Also consider the case when @id fields can be nullable.
					if len(oldObj) == 1 && len(obj) > 1 {
						// Continue execution to perform dfs in this case. There may be more nodes
						// in the subtree of this node.
						xidMetadata.variableObjMap[variable] = obj
					} else {
						// This is just a node reference. No need to proceed further.

View on GitHub (pinned to 759e242be6)

Solutions

  1. Deduplicate the input: send the object with that XID only once and reference it elsewhere by ID/XID.
  2. Split the mutation into multiple requests, each containing a single occurrence of the XID.
  3. Fix payload generators so nested objects are emitted once and reused as references.
  4. Check for inherited @id fields from interfaces causing the same value to appear in different implementing types.

Example fix

// before
addAuthor(input: [{ username: "alice", name: "A" }, { username: "alice", name: "A2" }])
// after
addAuthor(input: [{ username: "alice", name: "A" }]) // one occurrence only
Defensive patterns

Strategy: validation

Validate before calling

function assertNoDuplicateXids(objects, xidField) {
  const seen = new Set();
  for (const o of objects) {
    const key = o && o[xidField];
    if (key != null && key !== '') {
      if (seen.has(key)) throw new Error(`duplicate XID found: ${key}`);
      seen.add(key);
    }
  }
}

Try / catch

try {
  await client.mutate({ mutation: ADD_AUTHOR, variables: { input: authors } });
} catch (e) {
  if (/duplicate XID found/.test(e.message)) {
    const xid = e.message.match(/duplicate XID found: (.*)$/)[1];
    // dedupe authors by xid and resend
  } else throw e;
}

Prevention

When it happens

Trigger: A single add/update mutation whose input contains two or more objects sharing the same @id field value (e.g. two posts referencing author { username: "alice" } where alice's description appears twice), detected by isDuplicateXid during rewriting.

Common situations: Bulk-import payloads with repeated entities, list inputs generated from loops that re-emit the same parent object, or batch upserts combining set and nested references of the same XID.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/aae6848a3cc7418f. Report an issue: GitHub.