cocoindex-io/cocoindex · error · ValueError

Qdrant {kind} name must not be empty

Error message

Qdrant {kind} name must not be empty

What it means

Qdrant vector names must be non-empty strings. _validate_vector_names iterates every name in the vectors dict and raises this ValueError if any name is an empty string (or otherwise falsy). It is called from CollectionSchema.create for both dense and sparse named vectors (the `kind` parameter labels the message).

Source

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

        size=dim,
        distance=_distance_from_spec(vector_def.distance),
        multivector_config=multivector_config,
    )


def _sparse_vector_params_from_def(
    sparse_vector_def: _ResolvedQdrantSparseVectorDef,
) -> qdrant_models.SparseVectorParams:
    """Convert a resolved sparse vector definition to Qdrant SparseVectorParams."""
    return qdrant_models.SparseVectorParams(
        modifier=_sparse_modifier_from_spec(sparse_vector_def.modifier)
    )


def _validate_vector_names(names: Collection[str], kind: str) -> None:
    for name in names:
        if not name:
            raise ValueError(f"Qdrant {kind} name must not be empty")


_POINT_ID_RULE = (
    "Qdrant point IDs must be an unsigned 64-bit integer or a UUID "
    "(str or uuid.UUID); see "
    "https://qdrant.tech/documentation/manage-data/points/#point-ids. For a "
    "stable ID derived from an arbitrary string key, use uuid.uuid5, e.g. "
    'str(uuid.uuid5(uuid.NAMESPACE_URL, f"doc/{key}")).'
)


def _validate_point_id(raw: object) -> _PointId:
    """Validate a point ID against Qdrant's server-side rules, eagerly.

    Qdrant only accepts unsigned 64-bit integers and UUIDs (any textual
    form: hyphenated, 32-char hex, or URN); everything else is rejected at
    upsert time with an opaque transport error, so fail at declare time
    with an actionable one instead.

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Give every vector in the dict a non-empty name, e.g. vectors={"embedding": ...}.
  2. Filter or assert on names before calling create: assert all(names) for names in vectors.
  3. Fix the upstream config/code that produced the empty key.

Example fix

// before
await CollectionSchema.create(vectors={"": QdrantVectorDef(schema=vec, distance="cosine")})
// after
await CollectionSchema.create(vectors={"embedding": QdrantVectorDef(schema=vec, distance="cosine")})
Defensive patterns

Strategy: validation

Validate before calling

assert vectors and all(name for name in vectors), f"empty vector name in {list(vectors)}"

Type guard

isinstance(vectors, dict) and all(isinstance(k, str) and k for k in vectors)

Try / catch

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

Prevention

When it happens

Trigger: Passing a dict to CollectionSchema.create with an empty-string key, e.g. vectors={"": QdrantVectorDef(...)} — usually from programmatic name construction or config parsing that produced an empty name.

Common situations: Building vector names by concatenating prefixes and getting ""; config files where the vector name field is blank; dict comprehension over metadata where the key is missing/empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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