diff --git a/lib/crewai/src/crewai/knowledge/storage/knowledge_storage.py b/lib/crewai/src/crewai/knowledge/storage/knowledge_storage.py index 055763f7f..cfcbca25a 100644 --- a/lib/crewai/src/crewai/knowledge/storage/knowledge_storage.py +++ b/lib/crewai/src/crewai/knowledge/storage/knowledge_storage.py @@ -99,6 +99,9 @@ class KnowledgeStorage(BaseKnowledgeStorage): ) def save(self, documents: list[str]) -> None: + if not documents: + return + try: client = self._get_client() collection_name = ( @@ -177,6 +180,9 @@ class KnowledgeStorage(BaseKnowledgeStorage): Args: documents: List of document strings to save. """ + if not documents: + return + try: client = self._get_client() collection_name = ( diff --git a/lib/crewai/tests/knowledge/test_knowledge_storage_integration.py b/lib/crewai/tests/knowledge/test_knowledge_storage_integration.py index a58dcb2fc..44978bce4 100644 --- a/lib/crewai/tests/knowledge/test_knowledge_storage_integration.py +++ b/lib/crewai/tests/knowledge/test_knowledge_storage_integration.py @@ -193,3 +193,40 @@ def test_dimension_mismatch_error_handling(mock_get_client: MagicMock) -> None: with pytest.raises(ValueError, match="Embedding dimension mismatch"): storage.save(["test document"]) + + +@patch("crewai.knowledge.storage.knowledge_storage.get_rag_client") +def test_save_empty_documents_list(mock_get_client: MagicMock) -> None: + """Test that save() handles empty documents list gracefully. + + Calling save() with an empty documents list should be a no-op and not + propagate low-level storage exceptions from ChromaDB. + """ + mock_client = MagicMock() + mock_get_client.return_value = mock_client + + storage = KnowledgeStorage(collection_name="empty_docs_test") + + storage.save([]) + + mock_client.get_or_create_collection.assert_not_called() + mock_client.add_documents.assert_not_called() + + +@pytest.mark.asyncio +@patch("crewai.knowledge.storage.knowledge_storage.get_rag_client") +async def test_asave_empty_documents_list(mock_get_client: MagicMock) -> None: + """Test that asave() handles empty documents list gracefully. + + Calling asave() with an empty documents list should be a no-op and not + propagate low-level storage exceptions from ChromaDB. + """ + mock_client = MagicMock() + mock_get_client.return_value = mock_client + + storage = KnowledgeStorage(collection_name="empty_docs_async_test") + + await storage.asave([]) + + mock_client.aget_or_create_collection.assert_not_called() + mock_client.aadd_documents.assert_not_called()