{"record":{"id":"e856f8de175ca1b9","repo":"zeroclaw-labs/zeroclaw","slug":"qdrant-upsert-failed-status-text","errorCode":null,"errorMessage":"Qdrant upsert failed ({status}): {text}","messagePattern":"Qdrant upsert failed \\((.+?)\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-memory/src/qdrant.rs","lineNumber":977,"sourceCode":"                \"payload\": payload\n            }]\n        });\n\n        let resp = self\n            .request(\n                reqwest::Method::PUT,\n                &format!(\"/collections/{}/points\", self.collection),\n            )\n            .query(&[(\"wait\", \"true\")])\n            .json(&upsert_body)\n            .send()\n            .await\n            .context(\"failed to upsert point to Qdrant\")?;\n\n        if !resp.status().is_success() {\n            let status = resp.status();\n            let text = resp.text().await.unwrap_or_default();\n            anyhow::bail!(\"Qdrant upsert failed ({status}): {text}\");\n        }\n\n        Ok(())\n    }\n\n    async fn recall_for_agents(\n        &self,\n        allowed_agent_ids: &[&str],\n        query: &str,\n        limit: usize,\n        session_id: Option<&str>,\n        since: Option<&str>,\n        until: Option<&str>,\n    ) -> Result<Vec<MemoryEntry>> {\n        // Empty allowlist = no agent filter (matches the wrapper's\n        // semantics; see the SQL backends).\n        if allowed_agent_ids.is_empty() {\n            return self.recall(query, limit, session_id, since, until).await;","sourceCodeStart":959,"sourceCodeEnd":995,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-memory/src/qdrant.rs#L959-L995","documentation":"store_with_agent() upserts a freshly generated UUID point (vector + payload) via PUT /collections/{c}/points?wait=true. A non-2xx on that upsert raises this error. Because the point id is generated per call, blindly retrying store() creates a duplicate entry — fix the root cause or dedupe instead.","triggerScenarios":"400 'vector dimension mismatch' (collection built for a different embedding model); 404 collection dropped after init; 413 oversized payload; 5xx under memory pressure or OOM during indexing.","commonSituations":"Changed embedding provider (or model version) without recreating the collection — the classic cause; extremely large memory contents exceeding Qdrant limits; Qdrant OOM while indexing a burst of writes.","solutions":["Match dimensions (GET /collections/{c} -> vectors.size vs provider dims); export memories, recreate the collection under a new name, restart to rebuild, re-embed","413: store smaller content (split long documents before store)","5xx: check Qdrant memory/optimizer settings and retry once healthy; make retries idempotent by keying points on a content hash if you control the writer","404: recreate the collection and restart the process"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify dims match before write-heavy flows\nlet col: serde_json::Value = client.get(format!(\"{url}/collections/{c}\")).send().await?.json().await?;\nlet size = col.pointer(\"/result/config/params/vectors/size\").and_then(|v| v.as_u64());\nanyhow::ensure!(size == Some(embedder_dims as u64), \"collection dims {size:?} != embedder {embedder_dims}\");","typeGuard":"fn is_qdrant_upsert_error(e: &anyhow::Error) -> bool {\n    e.to_string().starts_with(\"Qdrant upsert failed\")\n}","tryCatchPattern":"// store() generates a fresh UUID per call, so dedupe instead of blind retry\nmatch memory.store(k, c).await {\n    Err(e) if is_qdrant_upsert_error(&e) => { memory.forget(k).await.ok(); memory.store(k, c).await }\n    other => other,\n}","preventionTips":["One embedding model per collection; migrate to a new collection when switching","Cap stored content size to avoid 413s","Export before model switches so re-embedding is possible","Make retries idempotent (dedupe by key) since point ids are per-call UUIDs"],"tags":["qdrant","upsert","embedding-dimensions","http-status","rust"],"backgroundTag":"vector-dimension-mismatch","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}