dgraph-io/dgraph · error

only one node is allowed in the filter while updating…

Error message

only one node is allowed in the filter while updating fields with @id directive

What it means

When updating a field with the @id directive, an upsert query is run first to locate the target node. If that query returns more than one node, the update cannot proceed unambiguously, so this error is thrown. The non-debug variant is returned when no query auth selector (queryAuthSelector) is configured for the mutated type.

Solutions

  1. Clean up duplicate nodes so the filter matches exactly one node
  2. Narrow the update filter to match a single node (unique @id value)
  3. Add an @auth query rule for the type so queryAuthSelector is non-nil (enables the debug variant/other path)
  4. Run the GraphQL debug variant to see which nodes matched

Example fix

// before
updateUser(input: { filter: { name: { eq: "Bob" } }, set: { email: "..." } }) // 2 Bobs
// after
updateUser(input: { filter: { xid: { eq: "user-42" } }, set: { email: "..." } })
Defensive patterns

Strategy: validation

Validate before calling

const nodes = await query({ filter });
if (xidsPresent && nodes.length > 1) {
  throw new Error('only one node is allowed in the filter while updating fields with @id directive');
}

Try / catch

try {
  await updateMutation(input);
} catch (err) {
  if (err.message.includes('only one node is allowed in the filter')) {
    // dedupe or narrow the filter
  }
}

Prevention

When it happens

Trigger: An update mutation touching an @id field whose filter matches multiple existing nodes (xidsPresent && len(result[name]) > 1), with no auth query rule defined for that type.

Common situations: Duplicate nodes with the same @id value from legacy imports; missing @auth(query: ...) rule so the system cannot disambiguate via auth; filter too broad (e.g. matching all nodes) when updating an @id field.

Related errors


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

Appendix: source

Thrown at graphql/resolve/mutation.go:459

							"mutation %s failed", mutation.Name())),
					resolverFailed
			}

			mutatedType := mutation.MutatedType()
			var xidsPresent bool
			if len(objSet) != 0 {
				for _, xid := range mutatedType.XIDFields() {
					if xidVal, ok := objSet[xid.Name()]; ok && xidVal != nil {
						xidsPresent = true
					}
				}
			}
			// if @id field is present in set and there are multiple nodes returned from
			// upsert query then we return error
			if xidsPresent && len(result[mutation.Name()].([]interface{})) > 1 {
				if queryAuthSelector(mutatedType) == nil {
					return emptyResult(
							schema.GQLWrapf(errors.Errorf("only one node is allowed in"+
								" the filter while updating fields with @id directive"),
								"mutation %s failed", mutation.Name())),
						resolverFailed
				}
				return emptyResult(
						schema.GQLWrapf(errors.Errorf("GraphQL debug: only one node is"+
							" allowed in the filter while updating fields with @id directive"),
							"mutation %s failed", mutation.Name())),
					resolverFailed

			}
		}

		copyTypeMap(upsert.NewNodes, newNodes)
	}
	mutationTimer.Stop()

	authErr := authorizeNewNodes(ctx, mutation, mutResp.Uids, newNodes, mr.executor, mutResp.Txn)

View on GitHub (pinned to 759e242be6)