dgraph-io/dgraph · error

ID "%s" isn't a %s

Error message

ID "%s" isn't a %s

What it means

During GraphQL mutation rewriting, a node referenced by its UID (ID field) was checked against the results of existence queries and no node with that UID exists in the database. Since referenced nodes must already exist, Dgraph rejects the mutation rather than silently creating a dangling reference. The error names the offending ID value and the expected type name.

Source

Thrown at graphql/resolve/mutation_rewriter.go:1393

				// We return an error if this is at toplevel. Else, we return the ID reference
				if atTopLevel {
					// We need to conceal the error because we might be leaking information to the user if it
					// tries to add duplicate data to the field with @id.
					var err error
					if queryAuthSelector(typ) == nil {
						err = x.GqlErrorf("id %s already exists for type %s", idVal.(string), typ.Name())
					} else {
						// This error will only be reported in debug mode.
						err = x.GqlErrorf("GraphQL debug: id already exists for type %s", typ.Name())
					}
					retErrors = append(retErrors, err)
					return nil, upsertVar, retErrors
				} else {
					return asIDReference(ctx, idVal, srcField, srcUID, varGen, mutationType == UpdateWithRemove), upsertVar, nil
				}
			} else {
				// Reference UID does not exist. This is an error.
				err := errors.Errorf("ID \"%s\" isn't a %s", idVal.(string), srcField.Type().Name())
				retErrors = append(retErrors, err)
				return nil, upsertVar, retErrors
			}
		}
	}

	xids := typ.XIDFields()
	if len(xids) != 0 {
		// multipleNodesForSameID is true when there are multiple nodes present
		// in a result of existence queries
		multipleNodesForSameID := gotMultipleExistingNodes(xids, obj, typ, varGen, idExistence)
		// xidVariables stores the variable names for each XID.
		var xidVariables []string
		for _, xid := range xids {
			var xidString string
			if xidVal, ok := obj[xid.Name()]; ok && xidVal != nil {
				xidString, _ = extractVal(xidVal, xid.Name(), xid.Type().Name())
				variable = varGen.Next(typ, xid.Name(), xidString, false)

View on GitHub (pinned to 759e242be6)

Solutions

  1. Query the node by that UID first to confirm it exists; create it (or use an upsert mutation with @id/XID) before referencing it.
  2. Use the node's external ID (XID) instead of the raw UID so Dgraph can run an existence query and reference or upsert correctly.
  3. Fix stale references in fixtures/seed data by regenerating UIDs from the target environment.
  4. Check the mutation structure: an ID reference at the top level of an Update mutation is allowed, but nested references must point to existing nodes.

Example fix

// before
addPost(input: { title: "hi", author: { id: "0x1234" } }) // 0x1234 does not exist
// after
addPost(input: { title: "hi", author: { username: "alice" } }) // reference via @id field, or create the author first
Defensive patterns

Strategy: validation

Validate before calling

async function uidExists(dgraph, uid, typeName) {
  const q = `query { n(func: uid(${uid})) @filter(type(${typeName})) { uid } }`;
  const res = await dgraph.newTxn().query(q);
  return res.data.n.length > 0;
}
// before the mutation: if (!(await uidExists(client, input.author.id, "Author"))) throw new Error("referenced Author does not exist");

Type guard

function isValidUid(v) {
  return typeof v === 'string' && /^0x[0-9a-fA-F]+$/.test(v);
}

Try / catch

try {
  await client.mutate({ mutation: ADD_POST, variables: { input } });
} catch (e) {
  if (/ID \".*\" isn't a/.test(e.message)) {
    // create the referenced node or switch to an @id/XID reference
  } else throw e;
}

Prevention

When it happens

Trigger: Calling an add/update mutation (e.g. addPost with set/add or update with a nested reference) where a nested object supplies an `id` field whose UID does not exist in Dgraph, and the mutation is not at top level (so it cannot be treated as an upsert/create).

Common situations: Hardcoded or copied UIDs from another environment (dev vs prod), deleted nodes still referenced by client code, stale test fixtures, or typos/truncation in a UID string.

Related errors


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