run-llama/llama_index · error · ValueError

No async database URI or engine provided, cannot initialize

Error message

No async database URI or engine provided, cannot initialize DB sessionmaker

What it means

SQLChatStore's async session factory (_get_async_sessionmaker) requires either an async_database_uri (e.g. 'sqlite+aiosqlite:///chat.db', 'postgresql+asyncpg://...') or an explicit async engine. If neither an async engine instance nor an async URI is configured at first async use, initialization raises immediately.

Source

Thrown at llama-index-core/llama_index/core/storage/chat_store/sql.py:132

    ) -> Tuple[AsyncEngine, sessionmaker]:
        """Set up database connections and session factories."""
        # Create async engine and session factory if async URI is provided
        if self._async_session_factory is not None and self._async_engine is not None:
            return self._async_engine, self._async_session_factory
        elif self.async_database_uri or self._async_engine:
            self._async_engine = self._async_engine or create_async_engine(
                self.async_database_uri
            )
            if self.async_database_uri is None:
                self.async_database_uri = self._async_engine.url

            self._async_session_factory = sessionmaker(  # type: ignore
                bind=self._async_engine, expire_on_commit=False, class_=AsyncSession
            )

            return self._async_engine, self._async_session_factory  # type: ignore
        else:
            raise ValueError(
                "No async database URI or engine provided, cannot initialize DB sessionmaker"
            )

    async def _setup_tables(self, async_engine: AsyncEngine) -> Table:
        """Set up database tables."""
        # Create metadata with schema
        if self.db_schema is not None and not self._is_sqlite_database():
            # Only set schema for databases that support it
            self._metadata = MetaData(schema=self.db_schema)

            # Create schema if it doesn't exist (PostgreSQL, SQL Server, etc.)
            async with async_engine.begin() as conn:
                await conn.execute(
                    text(f'CREATE SCHEMA IF NOT EXISTS "{self.db_schema}"')
                )

        # Create messages table with status column
        self._table = Table(

View on GitHub (pinned to afd0fef371)

Solutions

  1. Provide an async URI: SQLChatStore(async_database_uri='sqlite+aiosqlite:///chat.db', table_name='chat_store').
  2. Or pass a pre-built engine: create_async_engine(...) handed to SQLChatStore(async_engine=engine).
  3. Install the async driver if missing (pip install aiosqlite or asyncpg) so the +aiosqlite/+asyncpg URL resolves.
  4. For PostgreSQL pass both URIs: database_uri='postgresql+psycopg2://...' for sync paths and async_database_uri='postgresql+asyncpg://...' for async paths.

Example fix

# before
store = SQLChatStore(database_uri='sqlite:///chat.db')
msgs = await store.aget_messages('sess1')  # ValueError

# after
store = SQLChatStore(
    database_uri='sqlite:///chat.db',
    async_database_uri='sqlite+aiosqlite:///chat.db',
)
Defensive patterns

Strategy: validation

Validate before calling

def make_sql_chat_store(sync_uri: str | None, async_uri: str | None):
    if not (async_uri or ('+' in (sync_uri or '') and any(d in sync_uri for d in ('aiosqlite', 'asyncpg')))):
        raise ValueError('Provide async_database_uri or an async engine for async chat-store access')
    return SQLChatStore(database_uri=sync_uri, async_database_uri=async_uri)

Type guard

def supports_async(uri_or_engine) -> bool:
    if uri_or_engine is None:
        return False
    url = str(uri_or_engine)
    return any(d in url for d in ('aiosqlite', 'asyncpg', 'asyncmy'))

Try / catch

try:
    messages = await store.aget_messages(session_id)
except ValueError as e:
    if 'No async database URI' in str(e):
        messages = store.get_messages(session_id)  # fall back to sync path
    else:
        raise

Prevention

When it happens

Trigger: Constructing SQLChatStore(database_uri='sqlite:///chat.db') (sync URI only, no +aiosqlite) and then calling an async method such as aget_messages() or aset_messages(), which triggers async engine creation.

Common situations: Reusing a sync database URI string for an async-first app; FastAPI/asyncio services configured with the plain sqlite/postgres URL; forgetting the asyncpg/aiosqlite dialect prefix after switching from sync to async usage.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/469a1d2235de75e5. Report an issue: GitHub.