cayleygraph/cayley · error
not a nosql database: %T
Error message
not a nosql database: %T
What it means
nosql.Shape.BuildIterator requires the passed graph.QuadStore to be the concrete *nosql.QuadStore. Any other backend (memory, kv-wrapped stores, a mock) cannot execute nosql shape queries, so an iterator.Error carrying this message is returned instead of panicking.
Source
Thrown at graph/nosql/shapes.go:45
case shape.Composite:
if s2, opt := s.Simplify().Optimize(ctx, qs); opt {
return s2, true
}
}
return s, false
}
// Shape is a shape representing a documents query with filters
type Shape struct {
Collection string // name of the collection
Filters []nosql.FieldFilter // filters to select documents
Limit int64 // limits a number of documents
}
func (s Shape) BuildIterator(qs graph.QuadStore) iterator.Shape {
db, ok := qs.(*QuadStore)
if !ok {
return iterator.NewError(fmt.Errorf("not a nosql database: %T", qs))
}
return db.newIterator(s.Collection, s.Filters...)
}
func (s Shape) Optimize(ctx context.Context, r shape.Optimizer) (shape.Shape, bool) {
return s, false
}
// Quads is a shape representing a quads query
type Quads struct {
Links []Linkage // filters to select quads
Limit int64 // limits a number of documents
}
func (s Quads) BuildIterator(qs graph.QuadStore) iterator.Shape {
db, ok := qs.(*QuadStore)
if !ok {
return iterator.NewError(fmt.Errorf("not a nosql database: %T", qs))View on GitHub (pinned to 81dcd7d73e)
Solutions
- Open the database through the nosql-backed backend so BuildIterator receives *nosql.QuadStore
- Check which backend your config selected (storage flag) before issuing nosql shapes
- Wrap the returned iterator with error handling — the error surfaces as iterator.NewError, not a panic
- Use the backend-agnostic iterator APIs if you must support multiple QuadStore implementations
Example fix
// before
it := nosql.Shape{Collection: "quads"}.BuildIterator(qs)
// after
if _, ok := qs.(*nosql.QuadStore); !ok {
return nil, fmt.Errorf("nosql shapes need a nosql QuadStore, got %T", qs)
}
it := nosql.Shape{Collection: "quads"}.BuildIterator(qs) Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := qs.(*nosql.QuadStore); !ok { return fmt.Errorf("BuildIterator needs *nosql.QuadStore, got %T", qs) } Type guard
func asNoSQL(qs graph.QuadStore) (*nosql.QuadStore, bool) { s, ok := qs.(*nosql.QuadStore); return s, ok } Try / catch
it := shape.BuildIterator(qs)
if itErr := iterator.AsError(it); itErr != nil { // error-iterator check
return fmt.Errorf("iterator setup failed: %v", itErr)
} Prevention
- Match the query API to the backend you opened
- Check the storage backend name in your config
- Use nosql shapes only with nosql-backed stores
- Fail fast with your own type assertion for clearer messages
When it happens
Trigger: Calling shapes.Shape{...}.BuildIterator(qs) (or running a query via buildIterator) with a QuadStore that is not the nosql wrapper — e.g. qs came from graph.NewQuadStore("memstore", ...) instead of nosql.
Common situations: Mixing backends: opening a memstore or generic KV store but issuing nosql-specific shape queries; tests that pass a fake QuadStore.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- must execute a IteratorStep or PathStep
- no quad store in Iterate
- unexpected node type: %T
- expected KV quadstore, got: %T
- passed value was not a quad primitive: %T
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/764dccda90ee3b95.
Report an issue: GitHub.