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

  1. List at least one real column: return_columns=['content', 'metadata'].
  2. If you wanted all columns, enumerate them explicitly in the list.
  3. 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

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


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