cayleygraph/cayley · error

No context, graph not correctly initialised

Error message

No context, graph not correctly initialised

What it means

ApplyDeltas refuses to write any deltas when qs.context is nil, meaning the QuadStore was never initialized with an App Engine request context (getContext failed or was never called). No writes are attempted; the call fails fast.

Source

Thrown at graph/gaedatastore/quadstore.go:210

	}
	err := w.qs.ApplyDeltas(w.deltas, graph.IgnoreOpts{
		IgnoreDup: true,
	})
	w.deltas = w.deltas[:0]
	if err != nil {
		return 0, err
	}
	return len(buf), nil
}

func (w *quadWriter) Close() error {
	w.deltas = nil
	return nil
}

func (qs *QuadStore) ApplyDeltas(in []graph.Delta, ignoreOpts graph.IgnoreOpts) error {
	if qs.context == nil {
		return errors.New("No context, graph not correctly initialised")
	}
	toKeep := make([]graph.Delta, 0)
	for _, d := range in {
		if d.Action != graph.Add && d.Action != graph.Delete {
			//Defensive shortcut
			return errors.New("Datastore: invalid action")
		}
		key := qs.createKeyForQuad(d.Quad)
		keep := false
		switch d.Action {
		case graph.Add:
			found, err := qs.checkValid(key)
			if err != nil {
				return err
			}
			if found {
				if !ignoreOpts.IgnoreDup {
					return graph.ErrQuadExists

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Check the error returned at store creation — if it failed, do not use the store.
  2. Initialize the store inside a request handler with the HTTPRequest option so appengine.NewContext succeeds.
  3. Guard all write calls behind a successful initialization check of qs.context.
  4. If context expired, re-initialize the store with a fresh request rather than retrying writes.

Example fix

// before
if err := qs.AddQuad(q); err != nil { log.Fatal(err) }
// after
if qs.context == nil { return errors.New("store not initialized with request context") }
if err := qs.AddQuad(q); err != nil { log.Fatal(err) }
Defensive patterns

Strategy: validation

Validate before calling

if qs.context == nil {
    return errors.New("gaedatastore not initialized; pass HTTPRequest at New")
}
for _, d := range deltas {
    if d.Action != graph.Add && d.Action != graph.Delete {
        return fmt.Errorf("invalid action %v", d.Action)
    }
}

Type guard

func writable(qs *QuadStore) bool { return qs.context != nil }

Try / catch

if err := qs.ApplyDeltas(deltas, ignoreOpts); err != nil {
    if strings.Contains(err.Error(), "not correctly initialised") {
        // re-init store with current request, then retry once
    }
    return err
}

Prevention

When it happens

Trigger: Calling ApplyDeltas (directly or via WriteQuads, AddQuad, AddQuadSet, RemoveQuad, ApplyTransaction) on a QuadStore whose New/init path did not set qs.context — typically because the HTTPRequest option was missing.

Common situations: Initializing the store at package startup without a request, then trying to add quads per-request; a silent earlier getContext error that was ignored; reusing a store across App Engine instances after init failure.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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