{"record":{"id":"64d0e296701d446b","repo":"MemPalace/mempalace","slug":"delete-requires-either-ids-or-where","errorCode":null,"errorMessage":"delete requires either ids= or where=","messagePattern":"delete requires either ids= or where=","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/milvus.py","lineNumber":798,"sourceCode":"            )\n        return GetResult(\n            ids=[str(row.get(FIELD_ID, \"\")) for row in rows],\n            documents=[row.get(FIELD_DOCUMENT, \"\") for row in rows] if spec.documents else [],\n            metadatas=[self._extract_metadata(row) for row in rows] if spec.metadatas else [],\n            embeddings=[row.get(FIELD_VECTOR) or [] for row in rows] if spec.embeddings else None,\n        )\n\n    def get_all_metadata(self, where: Optional[dict] = None) -> list[dict]:\n        rows = self._collect_by_filter(\n            filter_expr=translate_where(where),\n            output_fields=[FIELD_ID, FIELD_METADATA],\n        )\n        return [self._extract_metadata(row) for row in rows]\n\n    def delete(self, *, ids=None, where=None):\n        filter_expr = translate_where(where)\n        if ids is None and where is None:\n            raise ValueError(\"delete requires either ids= or where=\")\n        if not self._remote_exists():\n            if self._marker_exists():\n                raise CollectionNotInitializedError(self._collection_name)\n            return\n        if ids is not None and where is not None:\n            rows = self._collect_by_filter(\n                filter_expr=filter_expr,\n                output_fields=[FIELD_ID],\n            )\n            allowed = {row[FIELD_ID] for row in rows}\n            ids = [doc_id for doc_id in ids if doc_id in allowed]\n        if ids is not None:\n            if not ids:\n                return\n            self._client.delete(collection_name=self._remote_collection, ids=list(ids))\n        else:\n            self._client.delete(collection_name=self._remote_collection, filter=filter_expr)\n","sourceCodeStart":780,"sourceCodeEnd":816,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/milvus.py#L780-L816","documentation":"Raised by MilvusCollection.delete() (mempalace/backends/milvus.py:798) when the method is called with neither ids= nor where=. delete() is keyword-only and needs at least one selector so it knows which rows to remove; an argumentless delete would otherwise wipe the collection, so the backend refuses instead of guessing.","triggerScenarios":"Calling collection.delete() with no arguments, or passing ids/where positionally (they are keyword-only: 'def delete(self, *, ids=None, where=None)'). Also calling delete(ids=[]) is fine, but delete(where={}) with an empty dict: 'where is None' is False so it passes, whereas delete() with both omitted triggers it.","commonSituations":"Copy-paste from a Chroma-like API where delete is also keyword-only but the caller forgot the filter; refactoring that builds a where clause conditionally and ends up passing None for both; interactive experimentation.","solutions":["Pass an explicit selector: collection.delete(ids=[...]) or collection.delete(where={...})","If you build filters dynamically, guard before calling: if ids or where: collection.delete(ids=ids, where=where)","To delete everything in the collection, use backend.delete_collection() / recreate instead of an argumentless delete","Remember both parameters are keyword-only: delete(ids=...) not delete([...])"],"exampleFix":"// before\ncollection.delete()\n\n# after\ncollection.delete(ids=['drawer-42'])\n# or\ncollection.delete(where={'wing': 'projects'})","handlingStrategy":"validation","validationCode":"def safe_delete(collection, ids=None, where=None):\n    if ids is None and where is None:\n        raise ValueError('refusing to delete without ids or where')\n    collection.delete(ids=ids, where=where)","typeGuard":"def is_delete_selector(ids, where) -> bool:\n    return ids is not None or where is not None","tryCatchPattern":"try:\n    collection.delete(ids=ids, where=where)\nexcept ValueError as e:\n    if 'requires either' in str(e):\n        # build a real selector and retry, never delete blindly\n        raise","preventionTips":["Never call delete() bare; always compute a selector first","Wrap dynamic-filter code: if ids or where: delete(...)","Treat 'delete everything' as delete_collection, not delete()"],"tags":["milvus","api-misuse","delete","validation"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}