{"record":{"id":"2e60ce44bffa1009","repo":"cayleygraph/cayley","slug":"no-quad-store-in-iterate","errorCode":null,"errorMessage":"no quad store in Iterate","messagePattern":"no quad store in Iterate","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graph/iterator/iterate.go","lineNumber":267,"sourceCode":"\t\t\tcase <-done:\n\t\t\t\treturn c.ctx.Err()\n\t\t\tdefault:\n\t\t\t}\n\t\t\ttags := make(map[string]refs.Ref, mn)\n\t\t\tc.it.TagResults(tags)\n\t\t\tif n := len(tags); n > mn {\n\t\t\t\tmn = n\n\t\t\t}\n\t\t\terr = fnc(tags)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn c.it.Err()\n}\n\nvar errNoQuadStore = fmt.Errorf(\"no quad store in Iterate\")\n\n// EachValue is an analog of Each, but it will additionally call NameOf\n// for each graph.Ref before passing it to a callback.\nfunc (c *Chain) EachValue(qs refs.Namer, fnc func(quad.Value) error) error {\n\tif qs != nil {\n\t\tc.qs = qs\n\t}\n\tif c.qs == nil {\n\t\treturn errNoQuadStore\n\t}\n\t// TODO(dennwc): batch NameOf?\n\treturn c.Each(func(v refs.Ref) error {\n\t\tnv, err := c.qs.NameOf(v)\n\t\tif err == nil && nv != nil {\n\t\t\terr = fnc(nv)\n\t\t}\n\t\treturn err\n\t})","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/graph/iterator/iterate.go#L249-L285","documentation":"The Chain iterator pipeline needs a quad store to resolve refs to values via NameOf (EachValue, FirstValue, SendValues, TagValues, etc.). If neither the value passed to the method nor the chain's stored qs is non-nil, errNoQuadStore is returned. It signals a programming mistake: value-resolution methods require a quad store.","triggerScenarios":"Calling chain.EachValue(qs, fnc) with a nil qs, or calling FirstValue/SendValues/TagValues on a Chain built without Attach/WithQuadStore and without passing a Namer, so c.qs stays nil.","commonSituations":"Building a chain via iterator.NewChain(...) in tests or custom code and forgetting iterator.NewChain(...).WithQuadStore(qs); passing nil where the Namer parameter is expected; refactoring that dropped the quad store attach step.","solutions":["Pass a valid refs.Namer (your *QuadStore) to EachValue/FirstValue instead of nil.","Attach the quad store to the chain at construction: use iterator.NewChain(...).WithQuadStore(qs) or c.Attach(qs).","For FirstValue, use the WithQuadStore variant or ensure the chain was created with a quad store bound.","Add a nil check on the store before invoking value-resolution methods in your code."],"exampleFix":"// before\nit := iterator.NewChain(p.Iterate())\nv, err := it.FirstValue(nil) // qs nil -> errNoQuadStore\n// after\nit := iterator.NewChain(p.Iterate()).WithQuadStore(qs)\nv, err := it.FirstValue(qs)","handlingStrategy":"type-guard","validationCode":"if qs == nil {\n    return fmt.Errorf(\"EachValue requires a non-nil quad store\")\n}","typeGuard":"func hasNamer(c *iterator.Chain, qs refs.Namer) bool {\n    return qs != nil\n}\n// only call EachValue/FirstValue when hasNamer is true","tryCatchPattern":"v, err := chain.FirstValue(qs)\nif err == iterator.ErrNoQuadStore {\n    return fmt.Errorf(\"chain built without quad store; attach via WithQuadStore\")\n}","preventionTips":["Always attach the quad store to chains with WithQuadStore at construction.","Never pass nil as the Namer argument to value-resolution methods.","Run iterator pipelines in tests with a real store to catch nil-qs misuse."],"tags":["iterator","nil-value","programming-error"],"backgroundTag":"null-argument","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"}