dgraph-io/dgraph · error
encountered an empty value for @id field `%s`
Error message
encountered an empty value for @id field `%s`
What it means
A field decorated with @id in the GraphQL schema received an empty string value in a mutation while being processed as a scalar or null value. @id fields uniquely identify nodes externally, so Dgraph forbids empty strings for them. The error names the offending field.
Source
Thrown at graphql/resolve/mutation_rewriter.go:2006
ctx, typ, fieldDef, varGen, object, xidMetadata, i)
} else {
fieldQueries, fieldTypes, err = existenceQueries(
ctx, fieldDef.Type(), fieldDef, varGen, object, xidMetadata)
}
retErrors = append(retErrors, err...)
ret = append(ret, fieldQueries...)
retTypes = append(retTypes, fieldTypes...)
default:
// This is a scalar list. So, it won't contain any XID.
// Don't do anything.
}
}
default:
// This field is either a scalar value or a null.
// Fields with ID directive cannot have empty values. Checking it here.
if fieldDef.HasIDDirective() && val == "" {
err := fmt.Errorf("encountered an empty value for @id field `%s`", fieldName)
retErrors = append(retErrors, err)
return nil, nil, retErrors
}
}
}
return ret, retTypes, retErrors
}
func existenceQueriesUnion(
ctx context.Context,
parentTyp schema.Type,
srcField schema.FieldDefinition,
varGen *VariableGenerator,
obj map[string]interface{},
xidMetadata *xidMetadata,
listIndex int) ([]*dql.GraphQuery, []string, []error) {
View on GitHub (pinned to 759e242be6)
Solutions
- Provide a real value for the @id field, or remove the field from the mutation input entirely.
- Sanitize payloads client-side: convert "" to null or drop the key before sending.
- If the field is genuinely optional, remove the @id directive from the schema.
- For bulk imports, pre-process rows to skip or fill blank @id cells.
Example fix
// before
addUser(input: { email: "", name: "Bob" })
// after
addUser(input: { email: "bob@example.com", name: "Bob" }) Defensive patterns
Strategy: validation
Validate before calling
const idFields = ["email", "username"];
function sanitizeInput(obj) {
for (const k of idFields) {
if (obj[k] === "") delete obj[k];
}
return obj;
} Type guard
function isValidIdValue(v) {
return v === undefined || v === null || (typeof v === 'string' && v.trim() !== '');
} Try / catch
try {
await client.mutate({ mutation: ADD_USER, variables: { input } });
} catch (e) {
if (/empty value for @id field/.test(e.message)) {
const f = e.message.match(/@id field `(\w+)`/)[1];
delete input[f]; // resend without the empty @id
} else throw e;
} Prevention
- Drop or null out empty strings for @id fields before mutating.
- Treat blank CSV/spreadsheet cells as missing values in importers.
- Validate @id fields against a non-empty-string rule in forms.
- Keep the schema's @id directive only on truly required fields.
When it happens
Trigger: Sending an add/update mutation where an @id field (e.g. `email`, `username`) is explicitly set to "" and the value reaches the default (scalar/null) branch of the value rewriting loop.
Common situations: HTML/JSON forms submitting empty strings, ORM or mapper layers converting missing values to "", or spreadsheets/CSV bulk imports with blank cells mapped to @id columns.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- only one node is allowed in the filter while updating fields
- GraphQL debug: only one node is allowed in the filter while
- field %s cannot be empty
- encountered an XID %s with %s that isn't a Int but data type
- encountered an XID %s with %s that isn't a Int64 but data ty
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/754fc62c18dad6f4.
Report an issue: GitHub.