cayleygraph/cayley · error

error checking quad validity: %v

Error message

error checking quad validity: %v

What it means

Returned by checkValidQuad when FindByKey on the quads collection returns an error other than ErrNotFound. A not-found quad is handled gracefully (returns false, nil), so this error signals a genuine database failure while reading a quad document during delta validation in ApplyDeltas.

Source

Thrown at graph/nosql/quadstore.go:301

	if err != nil {
		err = fmt.Errorf("quad update failed: %v", err)
	}
	return err
}

func checkQuadValid(q nosql.Document) bool {
	added, _ := asInt(q[fldQuadAdded])
	deleted, _ := asInt(q[fldQuadDeleted])
	return added > deleted
}

func (qs *QuadStore) checkValidQuad(ctx context.Context, key nosql.Key) (bool, error) {
	q, err := qs.db.FindByKey(ctx, colQuads, key)
	if err == nosql.ErrNotFound {
		return false, nil
	}
	if err != nil {
		err = fmt.Errorf("error checking quad validity: %v", err)
		return false, err
	}
	return checkQuadValid(q), nil
}

func (qs *QuadStore) batchInsert(col string) nosql.DocWriter {
	return nosql.BatchInsert(qs.db, col)
}

func (qs *QuadStore) appendLog(ctx context.Context, deltas []graph.Delta) ([]nosql.Key, error) {
	w := qs.batchInsert(colLog)
	defer w.Close()
	for _, d := range deltas {
		data, err := proto.Marshal(pquads.MakeQuad(d.Quad))
		if err != nil {
			return w.Keys(), err
		}
		var action string

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Check the wrapped driver error and fix the underlying read failure (connectivity, auth).
  2. Ensure the backend/driver maps missing documents/collections to nosql.ErrNotFound; upgrade the driver integration if not.
  3. Verify database credentials and that the quads collection exists.
  4. Retry ApplyDeltas after restoring connectivity; the read is side-effect free so retrying is safe.
  5. Use a context with adequate timeout for large delta batches.

Example fix

// before
q, err := qs.db.FindByKey(ctx, colQuads, key)
if err == nosql.ErrNotFound {
    return false, nil
}
// after
// caller-side guard: pre-check connectivity and retry reads
if err != nil {
    if isTransientDBErr(err) { // e.g. mongo.CommandError with network scope
        return qs.checkValidQuad(ctx, key) // safe: read-only
    }
    return false, err
}
Defensive patterns

Strategy: retry

Validate before calling

// read path: verify backend health before ApplyDeltas validation
if err := dbPing(ctx, spec); err != nil {
    return fmt.Errorf("cannot validate quads, DB unreadable: %w", err)
}

Try / catch

ok, err := validQuad(key) // via ApplyDeltas path
if err != nil && isTransient(err) {
    ok, err = retry(3, func() (bool, error) { return validQuad(key) }) // read is side-effect free
}

Prevention

When it happens

Trigger: ApplyDeltas validating a quad removal when the backing store read fails: connection dropped, ctx cancelled, authentication failure, or a corrupted key/document in the quads collection.

Common situations: Expired MongoDB credentials mid-run; network partition during ApplyDeltas; backend returning unexpected errors for missing collections (older driver versions that don't map missing collection to ErrNotFound).

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06). Data as JSON: /api/errors/de62dbd982cca8e4. Report an issue: GitHub.