cayleygraph/cayley · error
HTTP Request needed
Error message
HTTP Request needed
What it means
getContext in the Google App Engine datastore QuadStore requires an incoming *http.Request to derive an App Engine context (appengine.NewContext). If the graph.Options map does not contain a non-nil "HTTPRequest" entry, initialization fails and the quadstore cannot talk to the datastore. This is a mandatory option for this backend.
Source
Thrown at graph/gaedatastore/quadstore.go:157
}
if _, ok := err.(*datastore.ErrFieldMismatch); ok {
return true, nil
}
if err != nil {
clog.Warningf("Error occurred when getting quad/node %s %v", k, err)
return false, err
}
// a deleted node should not be returned as found.
if len(q.Deleted) >= len(q.Added) {
return false, nil
}
return true, nil
}
func getContext(opts graph.Options) (context.Context, error) {
req := opts["HTTPRequest"].(*http.Request)
if req == nil {
err := errors.New("HTTP Request needed")
clog.Errorf("%v", err)
return nil, err
}
return appengine.NewContext(req), nil
}
func (qs *QuadStore) ForRequest(r *http.Request) (graph.QuadStore, error) {
return &QuadStore{context: appengine.NewContext(r)}, nil
}
func (qs *QuadStore) NewQuadWriter() (quad.WriteCloser, error) {
return &quadWriter{qs: qs}, nil
}
type quadWriter struct {
qs *QuadStore
deltas []graph.Delta
}View on GitHub (pinned to 81dcd7d73e)
Solutions
- Obtain the store from within an HTTP handler and pass the request: opts["HTTPRequest"] = r in the graph.Options map.
- If not on App Engine, switch to a different quadstore backend (e.g. bolt, memory) via config instead of gaedatastore.
- Verify the option value is exactly *http.Request, not a wrapped or nil value.
- Check the appengine SDK import path matches your runtime (google.golang.org/appengine vs legacy appengine).
Example fix
// before
qs, err := graph.NewQuadStore("gaedatastore", "", graph.Options{})
// after (inside an http handler)
qs, err := graph.NewQuadStore("gaedatastore", "", graph.Options{"HTTPRequest": r}) Defensive patterns
Strategy: validation
Validate before calling
if req, ok := opts["HTTPRequest"].(*http.Request); !ok || req == nil {
return errors.New("gaedatastore requires opts[\"HTTPRequest\"] to be *http.Request")
} Type guard
func hasHTTPRequest(opts graph.Options) bool {
r, ok := opts["HTTPRequest"].(*http.Request)
return ok && r != nil
} Try / catch
qs, err := graph.NewQuadStore("gaedatastore", "", opts)
if err != nil {
return fmt.Errorf("gae store init failed: %w", err)
} Prevention
- Always open the gaedatastore inside an HTTP handler and pass r into graph.Options.
- Never ignore the error from NewQuadStore/New before using the store.
- Use a different backend if not running on App Engine.
- Assert the option type at startup with a small helper.
When it happens
Trigger: Calling gaedatastore.New (via graph.NewQuadStore / cayley config) without passing opts["HTTPRequest"], or passing something other than *http.Request (e.g. nil or wrong type).
Common situations: Running Cayley inside Google App Engine but opening the store outside an HTTP request handler; forgetting to forward the handler's r *http.Request into graph.Options; using an appengine backend in a non-GAE environment.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- No context, graph not correctly initialised
- Error updating log, context is nil, graph not correctly init
- context is nil, graph is not initialized
- context is nil, graph is not correctly initialized
- error fetching size, context is nil, graph not correctly ini
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/13923b45a4d0790c.
Report an issue: GitHub.