dgraph-io/dgraph · error
Subject and object both should be *. Got: %+v
Error message
Subject and object both should be *. Got: %+v
What it means
ToDeletePredEdge converts an NQuad of the canonical form `* predicate *` into a directed edge that drops the entire predicate. This error is thrown when the NQuad does not have BOTH subject and object equal to `*`, i.e. it is not a valid predicate-deletion directive (`Subject and object both should be *`). The library enforces this so partial-value deletions are not mistaken for dropping a whole predicate via alter.
Source
Thrown at dql/mutation.go:148
}
// CreateValueEdge returns a DirectedEdge with the given subject. The predicate,
// language, and facet values are derived from the NQuad.
func (nq NQuad) CreateValueEdge(subjectUid uint64) (*pb.DirectedEdge, error) {
var err error
out := nq.createEdgePrototype(subjectUid)
if err = copyValue(out, nq); err != nil {
return &emptyEdge, err
}
return out, nil
}
// ToDeletePredEdge takes an NQuad of the form '* p *' and returns the equivalent
// directed edge. Returns an error if the NQuad does not have the expected form.
func (nq NQuad) ToDeletePredEdge() (*pb.DirectedEdge, error) {
if nq.Subject != x.Star && nq.ObjectValue.String() != x.Star {
return &emptyEdge, errors.Errorf("Subject and object both should be *. Got: %+v", nq)
}
out := &pb.DirectedEdge{
// This along with edge.ObjectValue == x.Star would indicate
// that we want to delete the predicate.
Entity: 0,
Attr: nq.Predicate,
Namespace: nq.Namespace,
Lang: nq.Lang,
Facets: nq.Facets,
Op: pb.DirectedEdge_DEL,
}
if err := copyValue(out, nq); err != nil {
return &emptyEdge, err
}
return out, nil
}View on GitHub (pinned to 759e242be6)
Solutions
- Construct the NQuad with Subject = "*" and ObjectValue = "*" before calling ToDeletePredEdge.
- If you intend to delete one node's value, use a normal delete mutation (`<0x1> <age> * .`) instead of ToDeletePredEdge/alter.
- Check upstream code that copies fields into the NQuad and ensure it does not overwrite subject/object with concrete values.
- Validate the raw RDF line: only `* <pred> * .` is valid for predicate deletion.
Example fix
// before
nq := NQuad{Subject: "0x1", Predicate: "age", ObjectValue: star} // invalid
// after
nq := NQuad{Subject: x.Star, Predicate: "age", ObjectValue: &api.Value{Str: x.Star}}
edge, err := nq.ToDeletePredEdge() Defensive patterns
Strategy: validation
Validate before calling
func isPredDeleteNQuad(nq NQuad) bool {
return nq.Subject == "*" && nq.ObjectValue != nil && nq.ObjectValue.String() == "*"
} Type guard
func (nq NQuad) IsStarAll() bool {
return nq.Subject == "*" && nq.ObjectValue.String() == "*"
} Try / catch
edge, err := nq.ToDeletePredEdge()
if err != nil {
if strings.Contains(err.Error(), "Subject and object both should be *") {
return fmt.Errorf("predicate deletion requires exactly '* <pred> *': %w", err)
}
return err
} Prevention
- Only call ToDeletePredEdge on NQuads of the literal form `* <pred> *`.
- Use regular delete mutations for per-node value deletions, not alter/drop.
- Sanitize NQuads built from user RDF lines before routing them to alter.
When it happens
Trigger: Calling NQuad.ToDeletePredEdge (directly or via an alter/drop-attribute flow) with an NQuad whose Subject is not `x.Star` or whose ObjectValue is not `x.Star`, e.g. `<0x1> <age> *` or `* <age> "42"`.
Common situations: Building drop-predicate requests programmatically and populating subject/object with actual node ids or values instead of the literal `*`, or reusing a normal set/delete NQuad in a drop-all-attribute API call.
Related errors
- UID must to be greater than 0
- UID not found/generated for xid %s
- Subject should be > 0 for nquad: %+v
- ObjectId should be > 0 for nquad: %+v
- Unknown value type for nquad: %+v
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/87dbeb9b0d5ec291.
Report an issue: GitHub.