dgraph-io/dgraph · error

encountered an XID %s with %s that isn't a String

Error message

encountered an XID %s with %s that isn't a String

What it means

While extracting an @id (XID) value whose schema type is String or ID, Dgraph received a value that is not a JSON string. String/ID XIDs only accept string values, so the conversion via type assertion fails and the error names the XID field and type.

Source

Thrown at graphql/resolve/mutation_rewriter.go:2479

			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)
		}
		// "ID" is given as input for the @extended type mutation.
	case "String", "ID":
		xidString, ok := xidVal.(string)
		if !ok {
			return "", fmt.Errorf("encountered an XID %s with %s that isn't "+
				"a String", xidName, typeName)
		}
		return xidString, nil
	default:
		return "", fmt.Errorf("encountered an XID %s with %s that isn't"+
			"allowed as Xid", xidName, typeName)
	}
}

// This function will return interface type and variable for existence query on interface,
// if given xid is inherited from interface, otherwise it will return nil and empty string
func interfaceVariable(typ schema.Type, varGen *VariableGenerator, xidName string,
	xidString string) (schema.Type, string) {

	interfaceType, isInherited := typ.FieldOriginatedFrom(xidName)
	fieldDef := typ.Field(xidName)
	if isInherited && fieldDef.HasInterfaceArg() {
		return interfaceType, varGen.Next(typ, "Int."+xidName, xidString, false)

View on GitHub (pinned to 759e242be6)

Solutions

  1. Send the value as a JSON string (wrap it in quotes) in the mutation or its variables.
  2. Coerce client-side with String(value) before building the request.
  3. If numeric values are expected, change the @id field's schema type to Int or Int64.
  4. Fix client serialization so string-typed GraphQL variables are never emitted as numbers.

Example fix

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

Strategy: type-guard

Validate before calling

function assertStringXid(v, field) {
  if (typeof v !== 'string') throw new Error(`${field} must be a string for @id(String)`);
  return v;
}

Type guard

function isStringXid(v) {
  return typeof v === 'string';
}

Try / catch

try {
  await client.mutate({ mutation: ADD, variables: { input } });
} catch (e) {
  if (/isn't a String/.test(e.message)) {
    // coerce the value with String(v) and retry once
  } else throw e;
}

Prevention

When it happens

Trigger: An add/update mutation supplying a number, boolean, or other non-string JSON value for an @id field declared as String (or the ID scalar used for @extended type mutations).

Common situations: Clients passing unquoted numeric usernames/codes (12345 instead of "12345"), booleans from checkboxes mapped to string XIDs, or API gateways re-serializing strings as numbers.

Related errors


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