{"record":{"id":"a426af53bde75619","repo":"cayleygraph/cayley","slug":"token-not-valid","errorCode":null,"errorMessage":"token not valid","messagePattern":"token not valid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graph/gaedatastore/quadstore.go","lineNumber":468,"sourceCode":"\treturn qs.newAllIterator(quadKind)\n}\n\nfunc (qs *QuadStore) ValueOf(s quad.Value) (graph.Ref, error) {\n\tid := hashOf(s)\n\treturn &Token{Kind: nodeKind, Hash: id}, nil\n}\n\nfunc (qs *QuadStore) NameOf(val graph.Ref) (quad.Value, error) {\n\tif qs.context == nil {\n\t\treturn nil, errors.New(\"context is nil, graph is not initialized\")\n\t} else if v, ok := val.(refs.PreFetchedValue); ok {\n\t\treturn v.NameOf(), nil\n\t}\n\tvar key *datastore.Key\n\tif t, ok := val.(*Token); ok && t.Kind == nodeKind {\n\t\tkey = qs.createKeyFromToken(t)\n\t} else {\n\t\treturn nil, errors.New(\"token not valid\")\n\t}\n\n\t// TODO (panamafrancis) implement a cache\n\n\tnode := new(NodeEntry)\n\terr := datastore.Get(qs.context, key, node)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn quad.Raw(node.Name), nil\n}\n\nfunc (qs *QuadStore) Quad(val graph.Ref) (quad.Quad, error) {\n\tif qs.context == nil {\n\t\treturn quad.Quad{}, errors.New(\"context is nil, graph is not correctly initialized\")\n\t}\n\tvar key *datastore.Key\n\tif t, ok := val.(*Token); ok && t.Kind == quadKind {","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/graph/gaedatastore/quadstore.go#L450-L486","documentation":"NameOf expects the graph.Ref argument to be a *Token of Kind nodeKind so it can build a datastore key; anything else (a different Token kind, a non-Token ref) is rejected as invalid. It cannot resolve that reference to a node name.","triggerScenarios":"Passing a *Token whose Kind is quadKind, a raw hash string ref, or another ref type into NameOf; mixing up tokens returned from quad lookups with node tokens.","commonSituations":"Application code caching Tokens and passing the wrong kind; iterating quad tokens into NameOf; API changes where refs became Token-typed but callers pass pre-conversion values.","solutions":["Only pass Tokens obtained from NameFor/T-node paths (nodeKind) into NameOf.","Use a type check before calling: t, ok := val.(*Token); ok && t.Kind == nodeKind.","For quad tokens use Quad() instead of NameOf().","Inspect ref provenance — convert hashes with NameFor rather than passing raw refs."],"exampleFix":"// before\nname, err := qs.NameOf(quadToken) // wrong kind\n// after\nif t, ok := ref.(*Token); ok && t.Kind == nodeKind {\n    name, err = qs.NameOf(ref)\n}","handlingStrategy":"type-guard","validationCode":"if t, ok := ref.(*Token); !ok || t.Kind != nodeKind {\n    return errors.New(\"NameOf requires a nodeKind Token\")\n}","typeGuard":"func isNodeToken(ref graph.Ref) bool {\n    t, ok := ref.(*Token)\n    return ok && t.Kind == nodeKind\n}","tryCatchPattern":"val, err := qs.NameOf(ref)\nif err != nil {\n    if strings.Contains(err.Error(), \"token not valid\") {\n        // ref is not a node token; use Quad() for quad tokens\n    }\n    return err\n}","preventionTips":["Keep node tokens and quad tokens in separate variables/types at the call site.","Derive refs from NameFor or iterator results rather than ad-hoc values.","Assert token Kind before crossing API boundaries."],"tags":["datastore","token","invalid-argument","type-mismatch"],"backgroundTag":"invalid-argument-value","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}