dgraph-io/dgraph · error

encountered an XID %s with %s that isn't a Int but data type

Error message

encountered an XID %s with %s that isn't a Int but data type in schema is Int

What it means

While extracting an @id (XID) value declared as Int in the schema, Dgraph received a value of an unexpected runtime type (not json.Number nor int64). The schema says the XID is Int, but the supplied value cannot be converted, so it fails naming the XID field and schema type.

Source

Thrown at graphql/resolve/mutation_rewriter.go:2455

	for name, typ := range from {
		to[name] = typ
	}
}

func extractVal(xidVal interface{}, xidName, typeName string) (string, error) {
	switch typeName {
	case "Int":
		switch xVal := xidVal.(type) {
		case json.Number:
			val, err := xVal.Int64()
			if err != nil {
				return "", err
			}
			return strconv.FormatInt(val, 10), nil
		case int64:
			return strconv.FormatInt(xVal, 10), nil
		default:
			return "", fmt.Errorf("encountered an XID %s with %s that isn't "+
				"a Int but data type in schema is Int", xidName, typeName)
		}
	case "Int64":
		switch xVal := xidVal.(type) {
		case json.Number:
			val, err := xVal.Int64()
			if err != nil {
				return "", err
			}
			return strconv.FormatInt(val, 10), nil
		case int64:
			return strconv.FormatInt(xVal, 10), nil
		// If the xid field is of type Int64, both String and Int forms are allowed.
		case string:
			return xVal, nil
		default:
			return "", fmt.Errorf("encountered an XID %s with %s that isn't "+
				"a Int64 but data type in schema is Int64", xidName, typeName)

View on GitHub (pinned to 759e242be6)

Solutions

  1. Send the value as a JSON number without a fractional part (e.g. 123, not "123" or 123.0).
  2. Declare the @id field as String (or Int64, which accepts both) in the schema if IDs may arrive as strings.
  3. Coerce client-side: parse the string to an integer before passing it as a GraphQL variable.
  4. Check the mutation variables section — string-typed variables are the most common culprit.

Example fix

// before (variables)
{ "xid": "12345" }
// after
{ "xid": 12345 }
Defensive patterns

Strategy: type-guard

Validate before calling

function assertIntXid(v, field) {
  const n = typeof v === 'string' ? Number(v) : v;
  if (!Number.isInteger(n)) throw new Error(`${field} must be an integer for @id(Int)`);
  return n;
}

Type guard

function isIntLike(v) {
  return (typeof v === 'number' && Number.isInteger(v)) ||
         (typeof v === 'string' && /^-?\d+$/.test(v));
}

Try / catch

try {
  await client.mutate({ mutation: ADD, variables: { input } });
} catch (e) {
  if (/isn't a Int but data type in schema is Int/.test(e.message)) {
    // coerce the variable to a JSON integer and retry once
  } else throw e;
}

Prevention

When it happens

Trigger: An add/update mutation supplying a value for an @id field of schema type Int where the variable carries a string, float, or other non-numeric JSON type that the type switch in extractVal's "Int" case cannot handle.

Common situations: GraphQL variables passed as strings ("123" instead of 123), floats with decimal parts (123.0) not representable as Int, or clients serializing IDs as strings to avoid precision loss.

Related errors


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