Skip to content

bug(vector_stores/azure_ai_search): failed IndexingResult is ignored because the success check is inverted #6850

Description

@nothariharan

Component

Vector Store

Description

Summary

In the Python Azure AI Search vector store, failed insert / update / delete operations can return without raising. The success check is inverted for the Azure SDK's real return type (IndexingResult), so Mem0 can treat a failed Azure write as success.

The checks look like:

if not hasattr(doc, "status_code") and doc.get("status_code") != 201:
    raise Exception(...)

Azure SDK IndexingResult has status_code, so not hasattr(doc, "status_code") is always False. The and short-circuits and the exception is never raised — including when succeeded=False and the status is an error.

The TypeScript OSS Azure client already keys off result.succeeded. The Python path does not.

This is separate from #6732 (unguarded __del__) and #6566 (wildcard filters). Those do not touch this guard.

Steps to Reproduce

No live Azure account required — the bug is in the success-check logic. Against current main:

from types import SimpleNamespace
from unittest.mock import MagicMock, patch

# Minimal reproduction of the inverted guard (same shape as Azure IndexingResult)
doc = SimpleNamespace(
    succeeded=False,
    status_code=400,
    key="mem-1",
    error_message="The document is invalid.",
)

# Current main condition for insert:
if not hasattr(doc, "status_code") and doc.get("status_code") != 201:
    raise Exception(f"Insert failed: {doc}")

print("raised: no — failure was ignored")  # this is what happens today

Or via the store with a mocked client:

from types import SimpleNamespace
from unittest.mock import MagicMock, patch
from mem0.vector_stores.azure_ai_search import AzureAISearch

with patch("mem0.vector_stores.azure_ai_search.SearchIndexClient"), \
     patch("mem0.vector_stores.azure_ai_search.SearchClient") as MockSearchClient, \
     patch("mem0.vector_stores.azure_ai_search.AzureKeyCredential"):
    store = AzureAISearch(
        service_name="test",
        collection_name="test-index",
        api_key="test-key",
        embedding_model_dims=3,
    )
    store.search_client = MagicMock()
    store.search_client.upload_documents.return_value = [
        SimpleNamespace(
            succeeded=False,
            status_code=400,
            key="mem-1",
            error_message="The document is invalid.",
        )
    ]
    # On main: returns without raising
    store.insert(vectors=[[0.1, 0.2, 0.3]], payloads=[{"data": "x"}], ids=["mem-1"])
    print("insert returned OK despite succeeded=False")

Expected Behavior

When Azure returns IndexingResult(succeeded=False, ...), insert / update / delete should raise so callers (and Memory.add / update / delete paths) know the vector write failed.

Actual Behavior

Failures are ignored whenever the result object has a status_code attribute (the normal Azure SDK case). Mem0 can continue as if the memory was written to the index when it was not, which can leave history / entity state out of sync with the vector index.

Environment

  • mem0 version: main @ latest (guard present since the Azure AI Search provider landed; still on current main)
  • Python/Node version: Python 3.11
  • OS: Windows 11 (logic bug is platform-independent)

Metadata

Metadata

Assignees

No one assigned

    Labels

    vector-storeVector store backends (Qdrant, PGVector, Redis, etc.)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions