zeroclaw-labs/zeroclaw · error
Qdrant delete failed ({status}): {text}
Error message
Qdrant delete failed ({status}): {text} What it means
delete_points_matching POSTs /collections/{c}/points/delete with a filter; it implements forget(), forget_for_agent(), purge_session_for_agent(), purge_agent(), and the supersede step of store_with_agent(). This error means Qdrant refused the delete with a non-2xx status.
Source
Thrown at crates/zeroclaw-memory/src/qdrant.rs:491
async fn delete_points_matching(&self, fields: &[(&str, &str)]) -> Result<bool> {
self.ensure_initialized().await?;
let delete_body = serde_json::json!({"filter": Self::must_filter(fields)});
let resp = self
.request(
reqwest::Method::POST,
&format!("/collections/{}/points/delete", self.collection),
)
.query(&[("wait", "true")])
.json(&delete_body)
.send()
.await
.context("failed to delete from Qdrant")?;
if !resp.status().is_success() {
let status = resp.status();
let text = resp.text().await.unwrap_or_default();
anyhow::bail!("Qdrant delete failed ({status}): {text}");
}
Ok(true)
}
}
/// Qdrant point payload structure
#[derive(Debug, Clone, Serialize, Deserialize)]
struct MemoryPayload {
key: String,
content: String,
category: String,
timestamp: String,
#[serde(skip_serializing_if = "Option::is_none")]
session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
agent_id: Option<String>,
}View on GitHub (pinned to 88bb9c8533)
Solutions
- Check the status in the message; 404 means recreate the collection and restart the process so init re-runs
- 5xx/503: retry the forget after load drops or Qdrant reports ready — deletes are idempotent
- 400: inspect key/session_id values for characters that break the filter JSON
- Repeated lock timeouts: review Qdrant optimizer and memory settings
Defensive patterns
Strategy: retry
Type guard
fn is_qdrant_delete_error(e: &anyhow::Error) -> bool {
e.to_string().starts_with("Qdrant delete failed")
} Try / catch
for attempt in 0..3 {
match memory.forget(key).await {
Ok(n) => break,
Err(e) if is_qdrant_delete_error(&e) && attempt < 2 => { tokio::time::sleep(backoff(attempt)).await; }
Err(e) => return Err(e),
}
} // deletes are idempotent; a retry cannot double-delete Prevention
- Retry deletes with backoff on 5xx — they are idempotent
- Avoid rebuilding collections while purges run
- Alert on repeated 404s (collection dropped after init)
When it happens
Trigger: 404 collection missing (dropped after init); 400 malformed filter; 409/write-lock timeout under heavy upsert load; 5xx during Qdrant maintenance or optimization.
Common situations: Forgetting memories while the collection was rebuilt; deleting during heavy write traffic; Qdrant under memory pressure returning 503.
Related errors
- Qdrant collection creation failed ({status}): {text}
- Qdrant search failed ({status}): {text}
- Qdrant set payload failed during agent rename ({status}): {t
- Qdrant collection info failed ({status}): {text}
- Qdrant upsert failed ({status}): {text}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/031d58a59dd3498b.
Report an issue: GitHub.