crewAIInc/crewAI · error · RuntimeError

Pool lock not initialized

Error message

Pool lock not initialized

What it means

SnowflakeSearchTool._get_connection raises RuntimeError("Pool lock not initialized") when self._pool_lock is None. The lock (and pool) are only created in the dependency-bootstrap path inside __init__ when packages are present; if initialization was skipped or interrupted, async connection acquisition refuses to proceed rather than racing on an unprotected pool.

Source

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

                        ],
                        check=True,
                    )

                    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,

View on GitHub (pinned to 754d7323be)

Solutions

  1. Ensure the Snowflake dependencies are installed BEFORE constructing the tool so __init__ fully initializes the pool, lock, and thread pool.
  2. Do not catch-and-continue around tool construction — the ImportError at init is the root cause; fix it instead.
  3. Recreate the SnowflakeSearchTool instance if its state was cleared rather than reusing it.

Example fix

# before
try:
    tool = SnowflakeSearchTool(config=cfg)
except ImportError:
    pass  # later: await tool._get_connection() -> RuntimeError

# after
# pip install snowflake-connector-python snowflake-sqlalchemy cryptography
tool = SnowflakeSearchTool(config=cfg)
Defensive patterns

Strategy: validation

Validate before calling

tool = SnowflakeSearchTool(config=cfg)  # raises ImportError if deps missing
if getattr(tool, "_pool_lock", None) is None:
    raise RuntimeError("Tool not fully initialized; install Snowflake dependencies and recreate")

Try / catch

try:
    conn = await tool._get_connection()
except RuntimeError as e:
    if "not initialized" in str(e):
        tool = SnowflakeSearchTool(config=cfg)  # recreate after fixing deps
        conn = await tool._get_connection()
    else:
        raise

Prevention

When it happens

Trigger: The Snowflake packages were absent at __init__ (so _pool_lock was never assigned), and _get_connection is called afterwards; or object state was mutated/cleared externally (e.g. after close/cleanup) while a query is still in flight.

Common situations: Swallowing the ImportError from construction (try/except pass) and then calling the tool; reusing a tool instance after its resources were torn down; partial initialization when the auto-install prompt was declined.

Related errors


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