[BUG] SnowflakeSearchTool masks query failures with NameError and disables retries
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 74/100
Research direction
Locate SnowflakeSearchTool._execute_query and the mocked tests covering its database failures; first reproduce the query and cursor-creation cases described in the issue. Done means the original Snowflake errors surface, retry behavior is honored for retryable failures, and connections still return to the pool.
Written by the indexing model from the issue text.
Description
Description
SnowflakeSearchTool._execute_query() classifies retryable failures with except (DatabaseError, OperationalError), but those names are imported only under TYPE_CHECKING. At runtime they do not exist, so when a query fails, evaluating the except tuple raises NameError and replaces the actual Snowflake error — retry logic never runs.
A second masking path sits in the same finally: cursor.close() runs unconditionally, so when conn.cursor() itself raises, cleanup references an unassigned local and raises UnboundLocalError, hiding the original error.
This report was prepared with AI assistance. I cannot apply repository labels as an external contributor; please add the required
llm-generatedlabel.
Steps to reproduce
- Construct
SnowflakeSearchToolwith mockedsnowflake.connector.connect. - Make
cursor.executeraisesnowflake.connector.errors.DatabaseError("query failed"). - Call
await tool._execute_query("SELECT 1"). - Observe
NameError: name 'DatabaseError' is not definedinstead of theDatabaseError, with no retry. - Make
conn.cursorraise instead and observeUnboundLocalError.
Expected behavior
A database failure should propagate as the raised Snowflake error and honor the configured retry policy. A cursor-creation failure should also surface the original error. Connections should keep returning to the pool as before.
Screenshots/Code snippets
Current code:
if TYPE_CHECKING:
from snowflake.connector.errors import (
DatabaseError,
OperationalError,
)
...
except (DatabaseError, OperationalError) as e: # NameError at runtime
...
finally:
cursor.close() # UnboundLocalError when conn.cursor() raised
Operating System
macOS Sonoma
Python Version
3.13 (supported by the repository; not listed in the issue template)
crewAI Version
Current main (0374c631297f)
crewAI Tools Version
Current main (0374c631297f)
Virtual Environment
Venv (uv)
Evidence
Deterministic mocked tests reproduce both masking paths on current main (NameError / UnboundLocalError) and pass once the exception classes are bound at runtime and cursor cleanup is guarded. py_compile does not catch this because the names are looked up only when an exception reaches the except clause.
Possible Solution
Import DatabaseError/OperationalError inside the existing runtime try block next to import snowflake.connector, and guard cursor cleanup with a cursor = None sentinel.
Additional context
The existing suite passes today only because the happy path never evaluates the except tuple. No matching open issue or pull request was found for this area.
- Dominant language
- Python
- Stars
- 58.8k
- Forks
- 8.5k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 103
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from crewAIInc/crewAI
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
-
[BUG] AttributeError: 'int' object has no attribute 'get' in crew_run_tui.py during plan rendering Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
[BUG] crewai-cli's runtime pin uv~=0.11.6 installs a second, capped uv into every consumer .venv Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
All issues in crewAIInc/crewAI
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100