zeroclaw-labs/zeroclaw · error
Qdrant requires non-zero dimensional embeddings
Error message
Qdrant requires non-zero dimensional embeddings
What it means
store_with_agent() embeds "<key>\n<content>" via embed_one() and requires a non-empty vector because a Qdrant point must carry a vector. If the installed embedder is the no-op provider (dimensions() == 0, empty Vec output), every store fails with this error before any HTTP call. Scroll-based reads (get/list) keep working, which makes it look like a partial outage.
Source
Thrown at crates/zeroclaw-memory/src/qdrant.rs:935
}
async fn store_with_agent(
&self,
key: &str,
content: &str,
category: MemoryCategory,
session_id: Option<&str>,
_namespace: Option<&str>,
_importance: Option<f64>,
agent_id: Option<&str>,
) -> Result<()> {
self.ensure_initialized().await?;
let combined_text = format!("{}\n{}", key, content);
let embedder = self.embedder.read().clone();
let embedding = embedder.embed_one(&combined_text).await?;
if embedding.is_empty() {
anyhow::bail!("Qdrant requires non-zero dimensional embeddings");
}
let id = Uuid::new_v4().to_string();
let timestamp = Utc::now().to_rfc3339();
let resolved_agent_id = agent_id.unwrap_or("default").to_string();
let payload = MemoryPayload {
key: key.to_string(),
content: content.to_string(),
category: Self::category_to_str(&category),
timestamp,
session_id: session_id.map(str::to_string),
agent_id: Some(resolved_agent_id.clone()),
};
self.delete_points_matching(&[("key", key), ("agent_id", resolved_agent_id.as_str())])
.await
.context("qdrant pre-upsert cleanup failed")?;View on GitHub (pinned to 88bb9c8533)
Solutions
- Configure a real embedding provider for memory (model_provider with an embedding-capable profile) and restart
- If you don't want embeddings, switch the backend to sqlite (brain.db), which stores and searches without vectors
- After a config/set provider change, confirm QdrantMemory::embedder_dimensions() > 0 before writing
- Guard store call sites: skip or queue writes while dimensions are 0
Example fix
# before [memory] backend = "qdrant" # no model_provider -> Noop embedder; all stores fail # after [memory] backend = "qdrant" model_provider = "openai" # real embedder; stores now carry vectors
Defensive patterns
Strategy: validation
Validate before calling
// With the concrete QdrantMemory handle (before any store):
if qdrant_memory.embedder_dimensions() == 0 {
anyhow::bail!("configure an embedding provider before storing to the qdrant backend");
} Try / catch
match memory.store(key, content).await {
Err(e) if e.to_string().starts_with("Qdrant requires non-zero dimensional embeddings") => {
surface_config_error("memory backend needs model_provider with embeddings"); Ok(())
}
other => other,
} Prevention
- Never enable the qdrant backend without an embedding-capable model_provider
- Check embedder_dimensions() after any config/set provider change
- Use the sqlite backend when embeddings are unwanted
- Smoke-test one store() at startup to fail fast
When it happens
Trigger: Backend set to qdrant while the memory factory installed the Noop embedder (no embedding provider configured); the embedder was hot-swapped to a provider that returns empty vectors.
Common situations: Choosing the qdrant backend for semantic search without configuring model_provider; local setups without an API key for an embedding API; assuming qdrant stores raw text like the sqlite backend.
Related errors
- Qdrant collection creation failed ({status}): {text}
- Gmail OAuth token is not configured
- Gmail OAuth token is not configured for sending
- cloud_ops.iac_tools must not be empty when cloud_ops is enab
- gateway.path_prefix contains invalid character '{bad}'; only
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/dfa71a95205fe155.
Report an issue: GitHub.