chroma-core/chroma · error · TypeError

$knn key must be a string, got {type(key).__name__}

Error message

$knn key must be a string, got {type(key).__name__}

What it means

The optional 'key' field of $knn names the vector column to search (default '#embedding') and must be a string. Non-string keys - int, None, list - raise TypeError. Named keys matter in collections that store multiple embeddings per record.

Source

Thrown at chromadb/execution/expression/operator.py:727

            elif isinstance(query, (list, tuple, np.ndarray)):
                # Dense vector case - normalize then validate
                normalized = normalize_embeddings(query)
                if not normalized or len(normalized) > 1:
                    raise ValueError("$knn requires exactly one query embedding")

                # Validate the normalized version
                validate_embeddings(normalized)

                query = normalized[0]

            else:
                raise TypeError(
                    f"$knn query must be a list, numpy array, or SparseVector dict, got {type(query).__name__}"
                )

            key = knn_data.get("key", "#embedding")
            if not isinstance(key, str):
                raise TypeError(f"$knn key must be a string, got {type(key).__name__}")

            limit = knn_data.get("limit", 16)
            if not isinstance(limit, int):
                raise TypeError(
                    f"$knn limit must be an integer, got {type(limit).__name__}"
                )
            if limit <= 0:
                raise ValueError(f"$knn limit must be positive, got {limit}")

            return_rank = knn_data.get("return_rank", False)
            if not isinstance(return_rank, bool):
                raise TypeError(
                    f"$knn return_rank must be a boolean, got {type(return_rank).__name__}"
                )

            return Knn(
                query=query,
                key=key,

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Pass the column name as a string: {'key': '#embedding'}.
  2. Omit 'key' entirely to use the default.
  3. Map numeric column selectors to their string names before building the expression.

Example fix

# before
Search(rank={'$knn': {'query': emb, 'key': 0}})   # -> TypeError: got int

# after
Search(rank={'$knn': {'query': emb, 'key': '#embedding'}})
Defensive patterns

Strategy: validation

Validate before calling

key = knn_opts.get('key', '#embedding')
if not isinstance(key, str):
    raise TypeError(f'$knn key must be a string, got {type(key).__name__}')
Search(rank={'$knn': {'query': emb, 'key': key}})

Prevention

When it happens

Trigger: {'$knn': {'query': emb, 'key': 0}}; {'key': None}; {'key': ['#embedding']} with the name wrapped in a list; forwarding an int column index from a 'search field N' API.

Common situations: Supporting numeric column selectors and forwarding the index; form/query-string parsers producing lists ('?key=a,b'); configs distinguishing absent vs explicitly-null keys.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/28733688be42a8a5. Report an issue: GitHub.