crewAIInc/crewAI · error · ValueError

Invalid distance metric: {metric}

Error message

Invalid distance metric: {metric}

What it means

During _run, after connecting, DB2VectorSearchTool uppercases self.distance_metric and checks membership in self._ALLOWED_METRICS; anything else raises ValueError(f"Invalid distance metric: {metric}"). The allowlist exists because the metric is interpolated into the SQL distance function (e.g. VECTOR_COSINE/COSINE family), so arbitrary strings are both invalid and unsafe. The connection is already open when this fires, but no query has run.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/db2_search_tool/db2_search_tool.py:293

                indent=2,
            )

        try:
            query_vector = self._generate_embedding(query)

            # Explicit Connection Handling
            try:
                self._connect()
            except Exception as e:
                self._disconnect()  # Clean up any partial connection
                return json.dumps(
                    {"success": False, "error": f"Failed to connect to DB2: {e!s}"}
                )

            # Validate Metric
            metric = self.distance_metric.upper()
            if metric not in self._ALLOWED_METRICS:
                raise ValueError(f"Invalid distance metric: {metric}")

            # Validate Identifiers
            table = self._validate_identifier(self.table_name, allow_period=True)
            v_col = self._validate_identifier(self.vector_column)
            ret_cols = [self._validate_identifier(c) for c in self.return_columns]

            vector_dimension = len(query_vector)
            vector_string = str(query_vector)

            filter_clause = ""
            params = [vector_string]  # The vector string for the CLOB cast

            if filter_by and filter_value is not None:
                f_col = self._validate_identifier(filter_by)
                filter_clause = f"WHERE {f_col} = ?"
                params.append(filter_value)

            # DYNAMIC COLUMN SELECTION

View on GitHub (pinned to 754d7323be)

Solutions

  1. Use one of the allowed metric strings — check DB2VectorSearchTool._ALLOWED_METRICS for the installed version; typically 'COSINE', 'EUCLIDEAN', 'DOT' style names (e.g. distance_metric='COSINE').
  2. Print the allowlist once: print(DB2VectorSearchTool._ALLOWED_METRICS) to see exact accepted values.
  3. Guard configuration by validating distance_metric.upper() in _ALLOWED_METRICS before constructing the tool.

Example fix

# before
tool = DB2VectorSearchTool(table_name='docs', vector_column='embedding', return_columns=['id'], distance_metric='manhattan')

# after
tool = DB2VectorSearchTool(table_name='docs', vector_column='embedding', return_columns=['id'], distance_metric='EUCLIDEAN')
Defensive patterns

Strategy: validation

Validate before calling

metric = (distance_metric or 'COSINE').strip().upper()
if metric not in DB2VectorSearchTool._ALLOWED_METRICS:
    raise ValueError(f'Invalid distance metric: {metric}; allowed: {DB2VectorSearchTool._ALLOWED_METRICS}')
tool = DB2VectorSearchTool(..., distance_metric=metric)

Type guard

def is_allowed_metric(value: object) -> bool:
    return isinstance(value, str) and value.strip().upper() in DB2VectorSearchTool._ALLOWED_METRICS

Try / catch

try:
    tool._run(query_vector=vec, query_text=q)
except ValueError as e:
    if 'Invalid distance metric' in str(e):
        tool.distance_metric = 'COSINE'  # fall back to default and retry
        tool._run(query_vector=vec, query_text=q)
    else:
        raise

Prevention

When it happens

Trigger: DB2VectorSearchTool(..., distance_metric='manhattan') or 'dot' or 'euclidian' (typo) or 'cosine distance'; passing the metric with extra whitespace; assuming an abbreviation like 'l2' is supported.

Common situations: Porting code from another vector DB (pgvector, Pinecone) whose metric names differ; LLM-configured tools guessing metric names; typos and case variants (case is actually normalized, so only the name itself matters).

Related errors


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