cayleygraph/cayley · error · DeltaError
ErrQuadNotExist
ErrQuadNotExist
Error message
quad does not exist
What it means
ErrQuadNotExist is returned when a DELETE delta references a quad that is not present in the quadstore. Removal of a non-existent quad cannot be applied, so the transaction fails with this sentinel error (often wrapped in graph.DeltaError).
Source
Thrown at graph/quadwriter.go:84
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()
}
func (e *DeltaError) Unwrap() error {View on GitHub (pinned to 81dcd7d73e)
Solutions
- Verify the quad exists (qs lookup) before appending the Delete delta
- Treat as idempotent: filter the error with graph.IsQuadNotExist(err) and continue when absence is acceptable
- Ensure the Add that created the quad actually succeeded before queuing its Delete (check earlier deltas' errors)
- Re-fetch current quad state instead of relying on cached results that may be stale
Example fix
// before
err := qw.ApplyDeltas([]graph.Delta{{Action: graph.Delete, Quad: q}})
// after
err := qw.ApplyDeltas([]graph.Delta{{Action: graph.Delete, Quad: q}})
if err != nil && !graph.IsQuadNotExist(err) {
return err // deleting a missing quad is OK
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check before deleting
if qs.QuadExists(quad) { // or lookup the quad first
return qw.ApplyDeltas([]graph.Delta{{Action: graph.Delete, Quad: quad}})
}
return nil Type guard
func isQuadNotExist(err error) bool { return errors.Is(err, graph.ErrQuadNotExist) || graph.IsQuadNotExist(err) } Try / catch
err := qw.ApplyDeltas(deltas)
if err != nil {
if graph.IsQuadNotExist(err) {
// already gone: treat as success
} else {
return err
}
} Prevention
- Only queue Delete deltas for quads confirmed to exist
- Treat missing-quad deletes as idempotent no-ops
- Avoid deleting based on stale cached query results
- Check that the preceding Add delta succeeded before planning its delete
When it happens
Trigger: Applying a Delete delta for a quad that was never inserted or was already removed; gaedatastore ApplyDeltas hitting the default removal path where the quad lookup fails; writers that remove before add in a rollback path where the add never succeeded.
Common situations: Removing a quad twice (e.g. duplicate delete in a batch); deleting based on stale query results; rebase/rollback code that deletes quads that failed to insert; tests using mis-match (mis) expectations where the missing quad is tolerated.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/b606ed512a112555.
Report an issue: GitHub.