cayleygraph/cayley · error · DeltaError
ErrQuadExists
ErrQuadExists
Error message
quad exists
What it means
ErrQuadExists is returned when an ADD delta tries to insert a quad whose subject-predicate-object-context already exists in the quadstore. Cayley stores each unique quad once; inserting a duplicate is rejected rather than silently re-adding. It is typically wrapped in a graph.DeltaError carrying the offending delta.
Source
Thrown at graph/quadwriter.go:83
}
type Handle struct {
QuadStore
QuadWriter
}
type IgnoreOpts struct {
IgnoreDup, IgnoreMissing bool
}
func (h *Handle) Close() error {
err := h.QuadWriter.Close()
h.QuadStore.Close()
return err
}
var (
ErrQuadExists = errors.New("quad exists")
ErrQuadNotExist = errors.New("quad does not exist")
ErrInvalidAction = errors.New("invalid action")
ErrNodeNotExists = errors.New("node does not exist")
)
// DeltaError records an error and the delta that caused it.
type DeltaError struct {
Delta Delta
Err error
}
func (e *DeltaError) Error() string {
if !e.Delta.Quad.IsValid() {
return e.Err.Error()
}
return e.Delta.Action.String() + " " + e.Delta.Quad.String() + ": " + e.Err.Error()
}
View on GitHub (pinned to 81dcd7d73e)
Solutions
- Check for existence first with qs.Quad exists/contains lookup before adding, or filter deltas through graph.NewRemover/Add logic
- Skip or downgrade duplicates: pre-check each quad with a lookup and drop Add deltas for quads already stored
- For gaedatastore, set ignoreOpts.IgnoreDup so duplicate adds are treated as no-ops
- Compare errors with graph.IsQuadExist(err) and treat as success when duplicates are acceptable
Example fix
// before
err := qw.ApplyDeltas([]graph.Delta{{Action: graph.Add, Quad: q}})
// after
if !qs.QuadExists(q) { // or use graph.IsQuadExist(err) and ignore
err = qw.ApplyDeltas([]graph.Delta{{Action: graph.Add, Quad: q}})
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check before adding
if qs.QuadExists(quad) {
return nil // skip duplicate
}
return qw.ApplyDeltas([]graph.Delta{{Action: graph.Add, Quad: quad}}) Type guard
func isQuadExists(err error) bool { return errors.Is(err, graph.ErrQuadExists) || graph.IsQuadExist(err) } Try / catch
err := qw.ApplyDeltas(deltas)
if err != nil {
if graph.IsQuadExist(err) {
// duplicate add: safe to ignore or log
} else {
return err
}
} Prevention
- Make ingestion idempotent by pre-checking quad existence
- Enable IgnoreDup options when replaying datasets
- Deduplicate delta batches before submission
- Use graph.IsQuadExist to classify duplicates explicitly
When it happens
Trigger: Calling ApplyDeltas (or ApplyAddDeltas / a writer that uses it) with an Add delta for a quad already present in the store; in gaedatastore ApplyDeltas when the quad lookup finds the quad and IgnoreDup is not set; via WriteQuad with the Add action on an existing quad.
Common situations: Replaying the same dataset or N-Quads file twice into a store without deduplication; concurrent writers inserting the same quad; tests that insert fixtures then add them again; backfill jobs that are not idempotent.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/4874831a35c1a5cf.
Report an issue: GitHub.