crewAIInc/crewAI · error · ValueError
return_columns cannot be empty. At least one column must be
Error message
return_columns cannot be empty. At least one column must be specified for the SELECT query to be valid.
What it means
DB2VectorSearchTool._validate_return_columns is a Pydantic model_validator that rejects an empty return_columns list, because the tool builds a SELECT with those column names and SELECT with no columns is invalid SQL. The check runs at tool instantiation, so the tool object cannot even be constructed without at least one column. It is unrelated to connectivity or credentials.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/db2_search_tool/db2_search_tool.py:141
limit: int = Field(
default=3,
ge=1,
le=100,
description="Number of documents to return. Must be between 1 and 100.",
)
distance_metric: str = "COSINE"
max_distance: float | None = Field(
default=None,
ge=0.0,
description="Maximum allowed distance for results. Cannot be negative.",
)
@model_validator(mode="after")
def _validate_return_columns(self) -> DB2VectorSearchTool:
if not self.return_columns:
raise ValueError(
"return_columns cannot be empty. At least one column must be specified "
"for the SELECT query to be valid."
)
return self
db2_package: Any = Field(default=None, description="IBM DB2 base package.")
db2_dbi_package: Any = Field(default=None, description="IBM DB2 DBI package.")
custom_embedding_fn: ImportString[Callable[[str], list[float]]] | None = Field(
default=None,
description="Optional custom embedding function.",
)
connection: Any | None = None
dbi_connection: Any | None = None
cursor: Any | None = None
_openai_client: Any | None = None
View on GitHub (pinned to 754d7323be)
Solutions
- List at least one real column: return_columns=['content', 'metadata'].
- If you wanted all columns, enumerate them explicitly in the list.
- Fix the config loader so a missing key raises or defaults to a sensible non-empty list.
Example fix
# before tool = DB2VectorSearchTool(table_name='docs', vector_column='embedding', return_columns=[]) # after tool = DB2VectorSearchTool(table_name='docs', vector_column='embedding', return_columns=['id', 'content'])
Defensive patterns
Strategy: validation
Validate before calling
def make_db2_tool(table: str, vector_col: str, columns: list[str] | None, **kw):
if not columns:
raise ValueError('return_columns cannot be empty — list the columns to SELECT')
return DB2VectorSearchTool(table_name=table, vector_column=vector_col,
return_columns=columns, **kw) Type guard
def is_nonempty_str_list(value: object) -> bool:
return isinstance(value, list) and bool(value) and all(isinstance(c, str) and c for c in value) Try / catch
try:
tool = DB2VectorSearchTool(**cfg)
except ValidationError as e:
if 'return_columns' in str(e):
cfg['return_columns'] = ['id', 'content'] # sensible default, retry construction
tool = DB2VectorSearchTool(**cfg)
else:
raise Prevention
- Fail fast in config loading when the columns key is missing — never default to [].
- Enumerate columns explicitly; the tool does not support SELECT *.
- Add a pydantic/TypedDict config model with min_length=1 on the columns field.
When it happens
Trigger: DB2VectorSearchTool(table_name='docs', vector_column='embedding', return_columns=[]) or omitting return_columns when its default is empty; passing return_columns=None; a config loader producing an empty list for a missing config key.
Common situations: YAML/env-driven configuration where the columns key is absent and the loader yields []; teams intending 'SELECT *' — not supported, columns must be listed explicitly; refactor that moved the columns argument and left an empty default.
Related errors
- filter_by must be a non-empty column name.
- filter_by and filter_value must be provided together.
- Invalid distance metric: {metric}
- Query cannot be empty
- Invalid configuration for embedding provider '{provider}':\n
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/4639b22c0c25bb23.
Report an issue: GitHub.