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.

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.

Appendix: 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)