cayleygraph/cayley · error
gae quad: token not valid
Error message
gae quad: token not valid
What it means
Quad requires a *Token with Kind quadKind to construct the datastore key for the QuadEntry. Any other ref type or token kind yields this error, and the quad cannot be fetched.
Solutions
- Ensure the ref comes from quad iteration / quadsOf paths, i.e. has Kind quadKind.
- Type-check before calling: t, ok := val.(*Token); ok && t.Kind == quadKind.
- Use NameOf for nodeKind tokens instead.
- Fix serialization that flattens tokens and loses Kind information.
Example fix
// before
q, err := qs.Quad(nodeToken)
// after
if t, ok := ref.(*Token); ok && t.Kind == quadKind {
q, err = qs.Quad(ref)
} Defensive patterns
Strategy: type-guard
Validate before calling
if t, ok := ref.(*Token); !ok || t.Kind != quadKind {
return errors.New("Quad requires a quadKind Token")
} Type guard
func isQuadToken(ref graph.Ref) bool {
t, ok := ref.(*Token)
return ok && t.Kind == quadKind
} Try / catch
q, err := qs.Quad(ref)
if err != nil {
if strings.Contains(err.Error(), "token not valid") {
// wrong token kind; use NameOf for node tokens
}
return err
} Prevention
- Only pass tokens from quad iteration to Quad().
- Keep token Kind assertions at API boundaries.
- Avoid re-parsing serialized tokens that may lose Kind.
When it happens
Trigger: Passing a nodeKind Token, a raw hash ref, or a PreFetchedValue into Quad; mixing node and quad tokens when caching references.
Common situations: Confusing results of NameFor (node tokens) with QuadIterator tokens (quad tokens); refactoring across the old Value/Key API; storing token strings and re-parsing them incorrectly.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- token not valid
- Datastore: invalid action
- cannot count iterator without a valid context
- cannot scan %T to NodeHash
- did not pass a string predicate or a Path to FollowRecursive
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/5bdb8a89af6bf241.
Report an issue: GitHub.
Appendix: source
Thrown at graph/gaedatastore/quadstore.go:489
// TODO (panamafrancis) implement a cache
node := new(NodeEntry)
err := datastore.Get(qs.context, key, node)
if err != nil {
return nil, err
}
return quad.Raw(node.Name), nil
}
func (qs *QuadStore) Quad(val graph.Ref) (quad.Quad, error) {
if qs.context == nil {
return quad.Quad{}, errors.New("context is nil, graph is not correctly initialized")
}
var key *datastore.Key
if t, ok := val.(*Token); ok && t.Kind == quadKind {
key = qs.createKeyFromToken(t)
} else {
return quad.Quad{}, errors.New("gae quad: token not valid")
}
q := new(QuadEntry)
err := datastore.Get(qs.context, key, q)
if err != nil {
// Red herring error : ErrFieldMismatch can happen when a quad exists but a field is empty
if _, ok := err.(*datastore.ErrFieldMismatch); !ok {
return quad.Quad{}, err
}
}
var label interface{}
if q.Label != "" {
label = q.Label
}
return quad.Make(
q.Subject,
q.Predicate,
q.Object,View on GitHub (pinned to 81dcd7d73e)