PGVectorStore fails with GoogleGenerativeAIEmbeddings #86

Open
opened 2026-02-16 05:16:30 -05:00 by yindo · 6 comments
Owner

Originally created by @sergiocharpineljr on GitHub (Aug 20, 2025).

Originally assigned to: @averikitsch on GitHub.

The code below fails with the following error:

RuntimeError: Task <Task pending name='Task-3' coro=<AsyncPGVectorStore.asimilarity_search() running at xxx/.venv/lib/python3.12/site-packages/langchain_postgres/v2/async_vectorstore.py:689> cb=[_chain_future.<locals>._call_set_state() at /usr/lib/python3.12/asyncio/futures.py:394]> got Future <Task pending name='Task-4' coro=<InterceptedUnaryUnaryCall._invoke() running at xxx/.venv/lib/python3.12/site-packages/grpc/aio/_interceptor.py:652> cb=[InterceptedCall._fire_or_add_pending_done_callbacks()]> attached to a different loop

The above exception was the direct cause of the following exception:
...

    raise GoogleGenerativeAIError(f"Error embedding content: {e}") from e
langchain_google_genai._common.GoogleGenerativeAIError: Error embedding content: Task <Task pending name='Task-3' coro=<AsyncPGVectorStore.asimilarity_search() running at xxx/.venv/lib/python3.12/site-packages/langchain_postgres/v2/async_vectorstore.py:689> cb=[_chain_future.<locals>._call_set_state() at /usr/lib/python3.12/asyncio/futures.py:394]> got Future <Task pending name='Task-4' coro=<InterceptedUnaryUnaryCall._invoke() running at xxx/.venv/lib/python3.12/site-packages/grpc/aio/_interceptor.py:652> cb=[InterceptedCall._fire_or_add_pending_done_callbacks()]> attached to a different loop

Code:

import os
from dotenv import load_dotenv
from langchain_postgres import PGEngine, PGVectorStore
from langchain_google_genai import GoogleGenerativeAIEmbeddings

load_dotenv()
POSTGRES_USER = os.getenv("POSTGRES_USER")
POSTGRES_PASSWORD = os.getenv("POSTGRES_PASSWORD")
POSTGRES_HOST = os.getenv("POSTGRES_HOST")
POSTGRES_PORT = os.getenv("POSTGRES_PORT")
POSTGRES_DB = os.getenv("POSTGRES_DB")
TABLE_NAME = os.getenv("TABLE_NAME", "vectorstore")
VECTOR_SIZE = 1024

CONNECTION_STRING = (
    f"postgresql+psycopg://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_HOST}"
    f":{POSTGRES_PORT}/{POSTGRES_DB}"
)

pg_engine = PGEngine.from_connection_string(url=CONNECTION_STRING)

# Needed only for initialization
#pg_engine.init_vectorstore_table(
#    table_name=TABLE_NAME,
#    vector_size=VECTOR_SIZE,
#)
embeddings = GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001")
vector_store = PGVectorStore.create_sync(
    engine=pg_engine,
    table_name=TABLE_NAME,
    embedding_service=embeddings,
)

result = vector_store.similarity_search("My Search")
print(result)

Also tried with async versions of the methods but the error is the same.

Originally created by @sergiocharpineljr on GitHub (Aug 20, 2025). Originally assigned to: @averikitsch on GitHub. The code below fails with the following error: ``` RuntimeError: Task <Task pending name='Task-3' coro=<AsyncPGVectorStore.asimilarity_search() running at xxx/.venv/lib/python3.12/site-packages/langchain_postgres/v2/async_vectorstore.py:689> cb=[_chain_future.<locals>._call_set_state() at /usr/lib/python3.12/asyncio/futures.py:394]> got Future <Task pending name='Task-4' coro=<InterceptedUnaryUnaryCall._invoke() running at xxx/.venv/lib/python3.12/site-packages/grpc/aio/_interceptor.py:652> cb=[InterceptedCall._fire_or_add_pending_done_callbacks()]> attached to a different loop The above exception was the direct cause of the following exception: ... raise GoogleGenerativeAIError(f"Error embedding content: {e}") from e langchain_google_genai._common.GoogleGenerativeAIError: Error embedding content: Task <Task pending name='Task-3' coro=<AsyncPGVectorStore.asimilarity_search() running at xxx/.venv/lib/python3.12/site-packages/langchain_postgres/v2/async_vectorstore.py:689> cb=[_chain_future.<locals>._call_set_state() at /usr/lib/python3.12/asyncio/futures.py:394]> got Future <Task pending name='Task-4' coro=<InterceptedUnaryUnaryCall._invoke() running at xxx/.venv/lib/python3.12/site-packages/grpc/aio/_interceptor.py:652> cb=[InterceptedCall._fire_or_add_pending_done_callbacks()]> attached to a different loop ``` Code: ```python import os from dotenv import load_dotenv from langchain_postgres import PGEngine, PGVectorStore from langchain_google_genai import GoogleGenerativeAIEmbeddings load_dotenv() POSTGRES_USER = os.getenv("POSTGRES_USER") POSTGRES_PASSWORD = os.getenv("POSTGRES_PASSWORD") POSTGRES_HOST = os.getenv("POSTGRES_HOST") POSTGRES_PORT = os.getenv("POSTGRES_PORT") POSTGRES_DB = os.getenv("POSTGRES_DB") TABLE_NAME = os.getenv("TABLE_NAME", "vectorstore") VECTOR_SIZE = 1024 CONNECTION_STRING = ( f"postgresql+psycopg://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_HOST}" f":{POSTGRES_PORT}/{POSTGRES_DB}" ) pg_engine = PGEngine.from_connection_string(url=CONNECTION_STRING) # Needed only for initialization #pg_engine.init_vectorstore_table( # table_name=TABLE_NAME, # vector_size=VECTOR_SIZE, #) embeddings = GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001") vector_store = PGVectorStore.create_sync( engine=pg_engine, table_name=TABLE_NAME, embedding_service=embeddings, ) result = vector_store.similarity_search("My Search") print(result) ``` Also tried with async versions of the methods but the error is the same.
Author
Owner

@averikitsch commented on GitHub (Aug 22, 2025):

Thank you @sergiocharpineljr for the issue. I can confirm the error you are seeing.
A current work around is using the VertexAI library (https://pypi.org/project/langchain-google-vertexai/) with the same model like:

from langchain_google_vertexai import VertexAIEmbeddings
embeddings = VertexAIEmbeddings(model_name="gemini-embedding-001")
@averikitsch commented on GitHub (Aug 22, 2025): Thank you @sergiocharpineljr for the issue. I can confirm the error you are seeing. A current work around is using the VertexAI library (https://pypi.org/project/langchain-google-vertexai/) with the same model like: ``` from langchain_google_vertexai import VertexAIEmbeddings embeddings = VertexAIEmbeddings(model_name="gemini-embedding-001") ```
Author
Owner

@onestardao commented on GitHub (Aug 23, 2025):

@sergiocharpineljr

The workaround with VertexAIEmbeddings only sidesteps the issue it doesn’t fix the underlying incompatibility between GoogleGenerativeAIEmbeddings and PGVectorStore. This maps to an embedding/vector-store mismatch (ProblemMap No.8). If you’d like the full checklist and root-cause fix steps (beyond provider switching), let me know and I can share the reference.

@onestardao commented on GitHub (Aug 23, 2025): @sergiocharpineljr The workaround with `VertexAIEmbeddings` only sidesteps the issue it doesn’t fix the underlying incompatibility between `GoogleGenerativeAIEmbeddings` and PGVectorStore. This maps to an embedding/vector-store mismatch (ProblemMap No.8). If you’d like the full checklist and root-cause fix steps (beyond provider switching), let me know and I can share the reference.
Author
Owner

@emekauser commented on GitHub (Sep 5, 2025):

I am having the same issue, it makes the migration from PGVector to PGVectorStore incomplete

@emekauser commented on GitHub (Sep 5, 2025): I am having the same issue, it makes the migration from PGVector to PGVectorStore incomplete
Author
Owner

@onestardao commented on GitHub (Sep 6, 2025):

@emekauser

This isn’t just a provider-side glitch — it’s an embedding–vectorstore contract mismatch (ProblemMap No.8).
Using VertexAIEmbeddings sidesteps the GoogleGenerativeAIEmbeddings + PGVectorStore incompatibility, but it doesn’t really solve the underlying schema/metric drift.

If you want the minimal checklist and the root-cause steps (beyond provider switching), let me know and I can share the reference.

@onestardao commented on GitHub (Sep 6, 2025): @emekauser This isn’t just a provider-side glitch — it’s an embedding–vectorstore contract mismatch (ProblemMap No.8). Using `VertexAIEmbeddings` sidesteps the GoogleGenerativeAIEmbeddings + PGVectorStore incompatibility, but it doesn’t really solve the underlying schema/metric drift. If you want the minimal checklist and the root-cause steps (beyond provider switching), let me know and I can share the reference.
Author
Owner

@emekauser commented on GitHub (Sep 9, 2025):

Here is a working Example on how to use GoogleGenerativeEmbedding with PGVectorStore

_import os
import asyncpg
import asyncio

from langchain_postgres.utils.pgvector_migrator import alist_pgvector_collection_names, amigrate_pgvector_collection
from langchain_postgres import PGEngine, PGVectorStore, Column
from langchain.schema import Document
from langchain_google_genai import GoogleGenerativeAIEmbeddings
from dotenv import load_dotenv

load_dotenv()
db_name = os.getenv("DB_NAME")
db_user = os.getenv("DB_USER")
db_password = os.getenv("DB_PASSWORD")
db_host = os.getenv("DB_HOST")

if not db_name or not db_user or not db_password or not db_host:
raise ValueError(
"Database connection details are not set in the environment variables.")

VECTOR_SIZE = 3072
COLLECTION = "smart_ai_documents"
MODEL_NAME = "models/gemini-embedding-exp-03-07"
CONNECTION = f"postgresql+asyncpg://{db_user}:{db_password}@{db_host}:5432/{db_name}"

embedding = GoogleGenerativeAIEmbeddings(model=MODEL_NAME)
engine = PGEngine.from_connection_string(url=CONNECTION)

class VectorStoreInterface:
vector_store: PGVectorStore = None
embedding: GoogleGenerativeAIEmbeddings = None

def __init__(self):
    self.embedding = GoogleGenerativeAIEmbeddings(model=MODEL_NAME)

@classmethod
async def connect(cls):
    my_instance = cls()
    await my_instance.create_table_if_not_exist()
    await my_instance.init_vectorstore()
    return my_instance

async def is_table_exist(self):
    conn = await asyncpg.connect(CONNECTION.replace("+asyncpg", ""))
    exists = False
    try:
        query = """
            SELECT EXISTS (
                SELECT FROM
                    pg_tables
                WHERE
                    schemaname = $1 AND tablename = $2
            );
        """
        exists = await conn.fetchval(query, "public", COLLECTION)
    finally:
        await conn.close()
    return exists

async def create_table_if_not_exist(self):
    if not self.vector_store and not await self.is_table_exist():
        await engine.ainit_vectorstore_table(
            table_name=COLLECTION,
            vector_size=VECTOR_SIZE,
            id_column=Column("langchain_id", "VARCHAR")
        )

async def init_vectorstore(self):
    self.vector_store = await PGVectorStore.create(
        engine=engine,
        table_name=COLLECTION,
        embedding_service=self.embedding
    )

async def add_document(self, doc: Document, id: str):
    # Add the document to the vector store
    await self.add_documents(docs=[doc], ids=[id])

async def add_documents(self, docs: list[Document], ids: list[str]):
    # Add multiple documents to the vector store
    texts = [doc.page_content for doc in docs]
    embeddings = await self.embedding.aembed_documents(texts=texts)
    await self.vector_store.aadd_embeddings(texts=texts, embeddings=embeddings, ids=ids)

async def delete_document(self, id: str):
    # Delete a document from the vector store
    await self.vector_store.adelete(ids=[id])

async def get_document(self, id: str) -> Document | None:
    # Retrieve a document from the vector store
    results = await self.vector_store.aget_by_ids([id])
    return results[0] if results else None

async def search_documents(self, query: str, k: int = 5) -> list[Document]:
    """
    Search for documents in the vector store based on a query.
    Returns a list of Document objects.
    """
    embed_query = await self.embedding.aembed_documents(texts=[query])
    results = await self.vector_store.asimilarity_search_by_vector(embedding=embed_query[0])
    return results if results else []_
@emekauser commented on GitHub (Sep 9, 2025): **Here is a working Example on how to use GoogleGenerativeEmbedding with PGVectorStore** _import os import asyncpg import asyncio from langchain_postgres.utils.pgvector_migrator import alist_pgvector_collection_names, amigrate_pgvector_collection from langchain_postgres import PGEngine, PGVectorStore, Column from langchain.schema import Document from langchain_google_genai import GoogleGenerativeAIEmbeddings from dotenv import load_dotenv load_dotenv() db_name = os.getenv("DB_NAME") db_user = os.getenv("DB_USER") db_password = os.getenv("DB_PASSWORD") db_host = os.getenv("DB_HOST") if not db_name or not db_user or not db_password or not db_host: raise ValueError( "Database connection details are not set in the environment variables.") VECTOR_SIZE = 3072 COLLECTION = "smart_ai_documents" MODEL_NAME = "models/gemini-embedding-exp-03-07" CONNECTION = f"postgresql+asyncpg://{db_user}:{db_password}@{db_host}:5432/{db_name}" embedding = GoogleGenerativeAIEmbeddings(model=MODEL_NAME) engine = PGEngine.from_connection_string(url=CONNECTION) class VectorStoreInterface: vector_store: PGVectorStore = None embedding: GoogleGenerativeAIEmbeddings = None def __init__(self): self.embedding = GoogleGenerativeAIEmbeddings(model=MODEL_NAME) @classmethod async def connect(cls): my_instance = cls() await my_instance.create_table_if_not_exist() await my_instance.init_vectorstore() return my_instance async def is_table_exist(self): conn = await asyncpg.connect(CONNECTION.replace("+asyncpg", "")) exists = False try: query = """ SELECT EXISTS ( SELECT FROM pg_tables WHERE schemaname = $1 AND tablename = $2 ); """ exists = await conn.fetchval(query, "public", COLLECTION) finally: await conn.close() return exists async def create_table_if_not_exist(self): if not self.vector_store and not await self.is_table_exist(): await engine.ainit_vectorstore_table( table_name=COLLECTION, vector_size=VECTOR_SIZE, id_column=Column("langchain_id", "VARCHAR") ) async def init_vectorstore(self): self.vector_store = await PGVectorStore.create( engine=engine, table_name=COLLECTION, embedding_service=self.embedding ) async def add_document(self, doc: Document, id: str): # Add the document to the vector store await self.add_documents(docs=[doc], ids=[id]) async def add_documents(self, docs: list[Document], ids: list[str]): # Add multiple documents to the vector store texts = [doc.page_content for doc in docs] embeddings = await self.embedding.aembed_documents(texts=texts) await self.vector_store.aadd_embeddings(texts=texts, embeddings=embeddings, ids=ids) async def delete_document(self, id: str): # Delete a document from the vector store await self.vector_store.adelete(ids=[id]) async def get_document(self, id: str) -> Document | None: # Retrieve a document from the vector store results = await self.vector_store.aget_by_ids([id]) return results[0] if results else None async def search_documents(self, query: str, k: int = 5) -> list[Document]: """ Search for documents in the vector store based on a query. Returns a list of Document objects. """ embed_query = await self.embedding.aembed_documents(texts=[query]) results = await self.vector_store.asimilarity_search_by_vector(embedding=embed_query[0]) return results if results else []_
Author
Owner

@onestardao commented on GitHub (Sep 10, 2025):

@emekauser

Looks like you ran into a vectorstore contract mismatch — PGVector isn’t failing on its own, it’s the embedding→retrieval contract breaking (GoogleGenerativeAIEmbeddings vs PGVector indexing). That’s why the async patch above only sidesteps it.

I’ve been cataloguing these kinds of failures systematically. This one maps directly to the Global Fix Map (VectorDBs & Stores section):
👉 https://github.com/onestardao/WFGY/blob/main/ProblemMap/GlobalFixMap/README.md

If you want the short version:

enforce embedding dimension contracts (check at init, fail early if mismatch)

add a ΔS drift check between stored vectors vs query vectors

block ingestion when contracts fail, instead of letting it collapse silently

That way you don’t just patch for GoogleGenAI, you cover the same class of failures across FAISS, Qdrant, Redis, etc.

@onestardao commented on GitHub (Sep 10, 2025): @emekauser Looks like you ran into a vectorstore contract mismatch — PGVector isn’t failing on its own, it’s the embedding→retrieval contract breaking (GoogleGenerativeAIEmbeddings vs PGVector indexing). That’s why the async patch above only sidesteps it. I’ve been cataloguing these kinds of failures systematically. This one maps directly to the Global Fix Map (VectorDBs & Stores section): 👉 https://github.com/onestardao/WFGY/blob/main/ProblemMap/GlobalFixMap/README.md If you want the short version: enforce embedding dimension contracts (check at init, fail early if mismatch) add a ΔS drift check between stored vectors vs query vectors block ingestion when contracts fail, instead of letting it collapse silently That way you don’t just patch for GoogleGenAI, you cover the same class of failures across FAISS, Qdrant, Redis, etc.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langchain-postgres#86