cocoindex-io/cocoindex · error · ValueError
Invalid vector definition: {vectors}
Error message
Invalid vector definition: {vectors} What it means
CollectionSchema.create() in the Qdrant connector only accepts a QdrantVectorDef, a non-empty dict of names mapped to QdrantVectorDef/QdrantSparseVectorDef, or None (which has its own clearer error). Any other value — or a dict whose per-entry value is not a recognized vector def type — raises this ValueError. It is an upfront input-validation guard so invalid schemas fail in Python instead of at Qdrant collection creation time.
Source
Thrown at python/cocoindex/connectors/qdrant/_target.py:224
raise ValueError("Qdrant named vectors must not be empty")
_validate_vector_names(vectors.keys(), "vector")
resolved_entries: dict[
str, _ResolvedQdrantVectorDef | _ResolvedQdrantSparseVectorDef
] = {}
for name, vector_def in vectors.items():
if isinstance(vector_def, QdrantVectorDef):
resolved_entries[name] = await _resolve_vector_def(vector_def)
elif isinstance(vector_def, QdrantSparseVectorDef):
resolved_entries[name] = _resolve_sparse_vector_def(vector_def)
else:
raise ValueError(f"Invalid vector definition: {vector_def}")
resolved = _ResolvedQdrantNamedVectorsDef(vectors=resolved_entries)
elif vectors is None:
raise ValueError(
"Qdrant collection schema must declare at least one vector"
)
else:
raise ValueError(f"Invalid vector definition: {vectors}")
return cls(resolved)
@property
def vectors(
self,
) -> _ResolvedQdrantVectorDef | _ResolvedQdrantNamedVectorsDef:
"""Get vector definitions (all VectorSchemaProviders resolved)."""
return self._vectors
class _PointAction(NamedTuple):
point_id: _PointId
point: qdrant_models.PointStruct | None
class _PointHandler(coco.TargetHandler[qdrant_models.PointStruct, _PointFingerprint]):
_client: QdrantClient
_collection_name: strView on GitHub (pinned to e84aa99b32)
Solutions
- Wrap each vector configuration in QdrantVectorDef (or QdrantSparseVectorDef for sparse) instead of passing raw dicts or lists.
- If vectors is empty/None, pass at least one vector, e.g. CollectionSchema.create(vectors={"embedding": QdrantVectorDef(schema=VectorSchema(dtype=np.float32, size=384), distance="cosine")}).
- Pass sparse vectors only inside a dict (sparse vectors are always named in Qdrant).
- Print type(vectors) and each dict value's type to confirm they are the connector's def classes, not plain dicts.
Example fix
// before
await CollectionSchema.create(vectors={"embedding": {"size": 384, "distance": "cosine"}})
// after
from cocoindex.connectors.qdrant import QdrantVectorDef
await CollectionSchema.create(vectors={"embedding": QdrantVectorDef(schema=VectorSchema(dtype=np.float32, size=384), distance="cosine")}) Defensive patterns
Strategy: type-guard
Validate before calling
def _valid_vectors(v):
from cocoindex.connectors.qdrant import QdrantVectorDef, QdrantSparseVectorDef
if isinstance(v, QdrantVectorDef):
return True
return isinstance(v, dict) and bool(v) and all(
isinstance(x, (QdrantVectorDef, QdrantSparseVectorDef)) for x in v.values()
)
assert _valid_vectors(vectors), f"bad vectors: {type(vectors)}" Type guard
isinstance(vectors, QdrantVectorDef) or (isinstance(vectors, dict) and all(isinstance(d, (QdrantVectorDef, QdrantSparseVectorDef)) for d in vectors.values()))
Try / catch
try:
schema = await CollectionSchema.create(vectors=cfg["vectors"])
except ValueError as e:
raise ConfigError(f"qdrant vectors config invalid: {e}") from None Prevention
- Always build vector configs via QdrantVectorDef/QdrantSparseVectorDef classes, never raw dicts.
- Parse external config into def objects in one dedicated function so bad shapes fail early.
- Add a unit test that round-trips your config through CollectionSchema.create.
When it happens
Trigger: Calling `await CollectionSchema.create(vectors=...)` where `vectors` is not a QdrantVectorDef and not a dict (e.g. a list, a bare string, a QdrantSparseVectorDef handled elsewhere, or a dataclass-like object); or passing a dict whose value for some vector name is neither QdrantVectorDef nor QdrantSparseVectorDef (e.g. a raw dict or a dict of parameters).
Common situations: Hand-building the vectors config from YAML/JSON and forgetting to construct QdrantVectorDef objects; typos where a dict of plain kwargs is passed instead of the def class; mixing sparse vectors without wrapping them in QdrantSparseVectorDef inside a dict.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid vector definition: {vector_def}
- Qdrant {kind} name must not be empty
- Invalid Qdrant point ID {raw!r}: out of unsigned 64-bit rang
- expected None{loc}, got {type(value).__name__}
- expected {tp}{loc}, got {type(value).__name__}: {value!r}
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/9d8767b20ba59347.
Report an issue: GitHub.