Summary
EntityResolver in extract_and_store() (crates/zeph-memory/src/semantic/graph.rs) is built with .with_embedding_store(emb) but without .with_provider(&provider). Because provider is moved into GraphExtractor::new(provider, ...) at line 281, it is unavailable when the resolver is constructed.
Root cause
resolve_with_embedding_store() in resolver.rs has an early guard:
let (Some(emb_store), Some(provider)) = (self.embedding_store, self.provider) else {
return Ok(None);
};
Since self.provider is always None in production, store_entity_embedding() is never called → the zeph_graph_entities Qdrant collection is never populated → link_memory_notes() always receives Collection 'zeph_graph_entities' doesn't exist! errors → entities_processed=0, edges_created=0 on every turn.
Reproduction
Run with graph memory + Qdrant + orchestrator (embed = ollama). After two turns with related entities, the graph DB shows extracted entities in SQLite but:
- Qdrant has no
zeph_graph_entities collection
- All
note_linking: search failed with Collection not found
note linking completed entities_processed=0 edges_created=0
Observed in live session with config vector_backend = "qdrant", note_linking.enabled = true, orchestrator embed = "ollama".
Fix
Clone provider before passing to GraphExtractor::new(), then pass the clone to .with_provider() on the resolver:
let resolver = if let Some(ref emb) = embedding_store {
EntityResolver::new(&store)
.with_embedding_store(emb)
.with_provider(&provider) // ← add this
} else {
EntityResolver::new(&store)
};
Requires: provider.clone() passed to GraphExtractor::new() so provider is still available at the resolver construction site.
Impact
A-MEM note linking (similar_to edges) has never worked in production since the feature was introduced. PR #1827 fixed a separate issue (embedding store not passed to link_memory_notes), but this root cause was not caught because unit tests use MockProvider passed via .with_provider() directly — they bypass extract_and_store() entirely.
Summary
EntityResolverinextract_and_store()(crates/zeph-memory/src/semantic/graph.rs) is built with.with_embedding_store(emb)but without.with_provider(&provider). Becauseprovideris moved intoGraphExtractor::new(provider, ...)at line 281, it is unavailable when the resolver is constructed.Root cause
resolve_with_embedding_store()inresolver.rshas an early guard:Since
self.provideris alwaysNonein production,store_entity_embedding()is never called → thezeph_graph_entitiesQdrant collection is never populated →link_memory_notes()always receivesCollection 'zeph_graph_entities' doesn't exist!errors →entities_processed=0, edges_created=0on every turn.Reproduction
Run with graph memory + Qdrant + orchestrator (embed = ollama). After two turns with related entities, the graph DB shows extracted entities in SQLite but:
zeph_graph_entitiescollectionnote_linking: search failedwithCollection not foundnote linking completed entities_processed=0 edges_created=0Observed in live session with config
vector_backend = "qdrant",note_linking.enabled = true, orchestratorembed = "ollama".Fix
Clone
providerbefore passing toGraphExtractor::new(), then pass the clone to.with_provider()on the resolver:Requires:
provider.clone()passed toGraphExtractor::new()soprovideris still available at the resolver construction site.Impact
A-MEM note linking (
similar_toedges) has never worked in production since the feature was introduced. PR #1827 fixed a separate issue (embedding store not passed tolink_memory_notes), but this root cause was not caught because unit tests useMockProviderpassed via.with_provider()directly — they bypassextract_and_store()entirely.