{"record":{"id":"46ede258d294904e","repo":"cayleygraph/cayley","slug":"error-updating-log-context-is-nil-graph-not-corr","errorCode":null,"errorMessage":"Error updating log, context is nil, graph not correctly initialised","messagePattern":"Error updating log, context is nil, graph not correctly initialised","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graph/gaedatastore/quadstore.go","lineNumber":404,"sourceCode":"\t\terr := datastore.Get(c, key, foundMetadata)\n\t\tif err != nil && err != datastore.ErrNoSuchEntity {\n\t\t\tclog.Errorf(\"Error: %v\", err)\n\t\t\treturn err\n\t\t}\n\t\tfoundMetadata.QuadCount += quadsAdded\n\t\tfoundMetadata.NodeCount += nodesAdded\n\t\t_, err = datastore.Put(c, key, foundMetadata)\n\t\tif err != nil {\n\t\t\tclog.Errorf(\"Error: %v\", err)\n\t\t}\n\t\treturn err\n\t}, nil)\n\treturn err\n}\n\nfunc (qs *QuadStore) updateLog(in []graph.Delta) ([]int64, error) {\n\tif qs.context == nil {\n\t\terr := errors.New(\"Error updating log, context is nil, graph not correctly initialised\")\n\t\treturn nil, err\n\t}\n\tif len(in) == 0 {\n\t\treturn nil, errors.New(\"Nothing to log\")\n\t}\n\tlogEntries := make([]LogEntry, 0, len(in))\n\tlogKeys := make([]*datastore.Key, 0, len(in))\n\tfor _, d := range in {\n\t\tvar action string\n\t\tif d.Action == graph.Add {\n\t\t\taction = \"Add\"\n\t\t} else {\n\t\t\taction = \"Delete\"\n\t\t}\n\n\t\tentry := LogEntry{\n\t\t\tAction:    action,\n\t\t\tKey:       qs.createKeyForQuad(d.Quad).String(),","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/graph/gaedatastore/quadstore.go#L386-L422","documentation":"updateLog writes a LogEntry batch to the datastore for each applied delta; it needs the App Engine context to make the datastore call. A nil context means the store is not correctly initialized, so the log update cannot proceed.","triggerScenarios":"updateLog called (only from ApplyDeltas) after qs.context was nil — i.e. the store was created without a valid HTTPRequest-derived App Engine context; ApplyDeltas' nil check passed only if context was set, so this usually indicates a race or re-init clearing context.","commonSituations":"Store re-initialized or partially constructed concurrently while writes are in flight; earlier init error ignored; using the same QuadStore across different App Engine request scopes.","solutions":["Ensure the QuadStore is fully initialized (qs.context != nil) before writing; check New's error return.","Synchronize store initialization and writes; do not re-initialize a store mid-request.","Re-create the store inside the current request handler if the context is stale.","Add a nil-context guard before calling write APIs."],"exampleFix":"// before\nids, err := qs.updateLog(deltas) // may fail with nil context\n// after\nif qs.context == nil { return errors.New(\"gae context missing\") }\nids, err := qs.updateLog(deltas)","handlingStrategy":"validation","validationCode":"if qs.context == nil || len(deltas) == 0 {\n    return errors.New(\"cannot update log: missing context or empty deltas\")\n}","typeGuard":"func canLog(qs *QuadStore, ds []graph.Delta) bool { return qs.context != nil && len(ds) > 0 }","tryCatchPattern":"ids, err := qs.updateLog(deltas)\nif err != nil {\n    if strings.Contains(err.Error(), \"context is nil\") {\n        // re-initialize store with request context\n    }\n    return err\n}","preventionTips":["Initialize the store fully before writes.","Guard write paths with a nil-context check.","Avoid concurrent re-initialization of the QuadStore."],"tags":["appengine","logging","initialization","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}