dgraph-io/dgraph · error

not able to find set args in update mutation

Error message

not able to find set args in update mutation

What it means

An UpdateMutation requires a 'set' argument containing the fields to update. rewriteAndExecute extracts inp["set"] and, when it is absent/empty (len(objSet)==0, with the cast succeeding), fails the mutation because there is nothing to apply. This catches malformed update payloads where 'set' is an empty object.

Source

Thrown at graphql/resolve/mutation.go:439

		ext.TouchedUids += mutResp.GetMetrics().GetNumUids()[touchedUidsKey]
		if req.Query != "" && len(mutResp.GetJson()) != 0 {
			if err := json.Unmarshal(mutResp.GetJson(), &result); err != nil {
				return emptyResult(
						schema.GQLWrapf(err, "Couldn't unmarshal response from Dgraph mutation")),
					resolverFailed
			}
		}
		// for update mutation, if @id field is present in set then we check that
		// in filter only one node is selected. if there are multiple nodes selected,
		// then it's not possible to update all of them with same value of @id fields.
		// In that case we return error
		if mutation.MutationType() == schema.UpdateMutation {
			inp := mutation.ArgValue(schema.InputArgName).(map[string]interface{})
			setArg := inp["set"]
			objSet, okSetArg := setArg.(map[string]interface{})
			if len(objSet) == 0 && okSetArg {
				return emptyResult(
						schema.GQLWrapf(errors.Errorf("not able to find set args"+
							" in update mutation"),
							"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 {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Include at least one field in the set argument of the update mutation
  2. Validate the update payload client-side before sending (non-empty set object)
  3. If you only meant to filter/query, use a query instead of an update mutation
  4. Check GraphQL variables are actually populated (not {} due to serialization bug)

Example fix

// before
updatePost(input: { filter: { id: ["0x1"] }, set: {} })
// after
updatePost(input: { filter: { id: ["0x1"] }, set: { title: "new title" } })
Defensive patterns

Strategy: validation

Validate before calling

function validateUpdateInput(inp) {
  if (!inp || !inp.set || typeof inp.set !== 'object' || Object.keys(inp.set).length === 0) {
    throw new Error('update mutation requires a non-empty set argument');
  }
}

Type guard

function hasSetArg(inp) {
  return inp != null && typeof inp === 'object' &&
    inp.set != null && typeof inp.set === 'object' && Object.keys(inp.set).length > 0;
}

Try / catch

try {
  await client.mutate(UPDATE_MUTATION, { input });
} catch (err) {
  if (err.message.includes('not able to find set args')) {
    // fix payload: add fields to set
  }
}

Prevention

When it happens

Trigger: Sending an update mutation like updatePost(input: { filter: {...}, set: {} }) — an empty or missing set block; building the input programmatically and producing an empty map.

Common situations: Client templating bug that renders an empty set; filter-only update payloads copied from delete-style mutations; GraphQL variables passing an empty object for set.

Related errors


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