cayleygraph/cayley · error

no quad store in Iterate

Error message

no quad store in Iterate

What it means

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.

Source

Thrown at graph/iterator/iterate.go:267

			case <-done:
				return c.ctx.Err()
			default:
			}
			tags := make(map[string]refs.Ref, mn)
			c.it.TagResults(tags)
			if n := len(tags); n > mn {
				mn = n
			}
			err = fnc(tags)
			if err != nil {
				return err
			}
		}
	}
	return c.it.Err()
}

var errNoQuadStore = fmt.Errorf("no quad store in Iterate")

// EachValue is an analog of Each, but it will additionally call NameOf
// for each graph.Ref before passing it to a callback.
func (c *Chain) EachValue(qs refs.Namer, fnc func(quad.Value) error) error {
	if qs != nil {
		c.qs = qs
	}
	if c.qs == nil {
		return errNoQuadStore
	}
	// TODO(dennwc): batch NameOf?
	return c.Each(func(v refs.Ref) error {
		nv, err := c.qs.NameOf(v)
		if err == nil && nv != nil {
			err = fnc(nv)
		}
		return err
	})

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Pass a valid refs.Namer (your *QuadStore) to EachValue/FirstValue instead of nil.
  2. Attach the quad store to the chain at construction: use iterator.NewChain(...).WithQuadStore(qs) or c.Attach(qs).
  3. For FirstValue, use the WithQuadStore variant or ensure the chain was created with a quad store bound.
  4. Add a nil check on the store before invoking value-resolution methods in your code.

Example fix

// before
it := iterator.NewChain(p.Iterate())
v, err := it.FirstValue(nil) // qs nil -> errNoQuadStore
// after
it := iterator.NewChain(p.Iterate()).WithQuadStore(qs)
v, err := it.FirstValue(qs)
Defensive patterns

Strategy: type-guard

Validate before calling

if qs == nil {
    return fmt.Errorf("EachValue requires a non-nil quad store")
}

Type guard

func hasNamer(c *iterator.Chain, qs refs.Namer) bool {
    return qs != nil
}
// only call EachValue/FirstValue when hasNamer is true

Try / catch

v, err := chain.FirstValue(qs)
if err == iterator.ErrNoQuadStore {
    return fmt.Errorf("chain built without quad store; attach via WithQuadStore")
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06). Data as JSON: /api/errors/2e60ce44bffa1009. Report an issue: GitHub.