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

  1. Construct the NQuad with Subject = "*" and ObjectValue = "*" before calling ToDeletePredEdge.
  2. If you intend to delete one node's value, use a normal delete mutation (`<0x1> <age> * .`) instead of ToDeletePredEdge/alter.
  3. Check upstream code that copies fields into the NQuad and ensure it does not overwrite subject/object with concrete values.
  4. 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

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


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