cocoindex-io/cocoindex · error · ValueError

Unsupported Qdrant sparse vector modifier: {modifier}

Error message

Unsupported Qdrant sparse vector modifier: {modifier}

What it means

For sparse vectors, Qdrant supports an optional modifier; the connector accepts only "idf" (inverse document frequency) or None. Any other modifier value on QdrantSparseVectorDef raises this ValueError when sparse vector params are built.

Source

Thrown at python/cocoindex/connectors/qdrant/_target.py:685


def _multivector_comparator(
    comparator: str,
) -> qdrant_models.MultiVectorComparator:
    """Convert multivector comparator string to Qdrant enum."""
    if comparator.lower() == "max_sim":
        return qdrant_models.MultiVectorComparator.MAX_SIM
    raise ValueError(f"Unsupported multivector comparator: {comparator}")


def _sparse_modifier_from_spec(
    modifier: Literal["idf"] | None,
) -> qdrant_models.Modifier | None:
    if modifier is None:
        return None
    if modifier == "idf":
        return qdrant_models.Modifier.IDF
    raise ValueError(f"Unsupported Qdrant sparse vector modifier: {modifier}")


def _vector_params_from_def(
    vector_def: _ResolvedQdrantVectorDef,
) -> qdrant_models.VectorParams:
    """Convert a resolved vector definition to Qdrant VectorParams."""
    resolved_schema = vector_def.schema
    multivector_config = None

    if isinstance(resolved_schema, res_schema.VectorSchema):
        dim = resolved_schema.size
    elif isinstance(resolved_schema, res_schema.MultiVectorSchema):
        dim = resolved_schema.vector_schema.size
        # For multivector, use the specified comparator
        multivector_config = qdrant_models.MultiVectorConfig(
            comparator=_multivector_comparator(vector_def.multivector_comparator)
        )
    else:

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Set modifier="idf" (exact lowercase) or omit it / pass None.
  2. If you typed "IDF" or "Idf", lowercase it.
  3. If you don't want IDF weighting, delete the modifier field rather than passing "none".

Example fix

// before
QdrantSparseVectorDef(modifier="IDF")
// after
QdrantSparseVectorDef(modifier="idf")
Defensive patterns

Strategy: validation

Validate before calling

assert modifier in (None, "idf"), f"modifier must be None or 'idf', got {modifier!r}"

Type guard

modifier is None or modifier == "idf"

Try / catch

try:
    schema = await CollectionSchema.create(vectors={"sparse": QdrantSparseVectorDef(modifier=mod)})
except ValueError as e:
    raise ConfigError(f"sparse modifier invalid: {e}") from None

Prevention

When it happens

Trigger: Setting `modifier=` on QdrantSparseVectorDef to a value other than None or "idf" (e.g. "IDF" uppercase — matching is exact here — "bm25", or "none"); triggered via _sparse_vector_params_from_def during collection creation.

Common situations: Assuming case-insensitive matching (unlike the comparator helper, this one is exact, so "IDF" fails); copying modifier names from other engines; using a placeholder like "none" instead of omitting the field.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/c1b362771e4c4d7d. Report an issue: GitHub.