crewAIInc/crewAI · error · RuntimeError

Connection pool not initialized

Error message

Connection pool not initialized

What it means

SnowflakeSearchTool._get_connection raises RuntimeError("Connection pool not initialized") when self._connection_pool is None. Like the pool-lock check, it guards the async path against use of a half-initialized tool: the pool list is created during __init__ only when the Snowflake dependency branch completes successfully.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/snowflake_search_tool/snowflake_search_tool.py:165

                    )

                    self._connection_pool = []
                    self._pool_lock = threading.Lock()
                    self._thread_pool = ThreadPoolExecutor(max_workers=self.pool_size)
                except subprocess.CalledProcessError as e:
                    raise ImportError("Failed to install Snowflake dependencies") from e
            else:
                raise ImportError(
                    "Snowflake dependencies not found. Please install them by running "
                    "`uv add cryptography snowflake-connector-python snowflake-sqlalchemy`"
                ) from None

    async def _get_connection(self) -> SnowflakeConnection:
        """Get a connection from the pool or create a new one."""
        if self._pool_lock is None:
            raise RuntimeError("Pool lock not initialized")
        if self._connection_pool is None:
            raise RuntimeError("Connection pool not initialized")
        with self._pool_lock:
            if self._connection_pool:
                return self._connection_pool.pop()
        return await asyncio.get_event_loop().run_in_executor(
            self._thread_pool, self._create_connection
        )

    def _create_connection(self) -> SnowflakeConnection:
        """Create a new Snowflake connection."""
        conn_params: dict[str, Any] = {
            "account": self.config.account,
            "user": self.config.user,
            "warehouse": self.config.warehouse,
            "database": self.config.database,
            "schema": self.config.snowflake_schema,
            "role": self.config.role,
            "session_parameters": self.config.session_parameters,
        }

View on GitHub (pinned to 754d7323be)

Solutions

  1. Install the Snowflake dependencies and re-instantiate the tool so __init__ creates the pool.
  2. If subclassing, ensure super().__init__() runs and do not clear _connection_pool while queries are in flight.
  3. Avoid reusing an instance after cleanup; create a fresh one per session.
Defensive patterns

Strategy: validation

Validate before calling

if getattr(tool, "_connection_pool", None) is None:
    raise RuntimeError("Connection pool missing; re-create the tool with Snowflake deps installed")
result = await tool._run(query=sql)

Try / catch

try:
    await tool._run(query=sql)
except RuntimeError as e:
    if "Connection pool not initialized" in str(e):
        # recreate instance; do not retry on the broken one
        raise

Prevention

When it happens

Trigger: Calling _run/_get_connection on a tool whose __init__ did not complete the dependency branch (packages missing, install declined or failed), or after pool state was reset; the lock check fires first if both are None, so this specific message means _pool_lock exists but the pool list does not.

Common situations: State cleared during close/cleanup while a concurrent query still runs; subclasses that override or interfere with __init__ initialization order; swallowing init errors and continuing.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/5dc781cb1205d9f2. Report an issue: GitHub.