{"record":{"id":"a0ee36660040bf84","repo":"apache/beam","slug":"embeddableitem-must-have-at-least-one-embedding-dense-or","errorCode":null,"errorMessage":"EmbeddableItem must have at least one embedding (dense or sparse)","messagePattern":"EmbeddableItem must have at least one embedding \\(dense or sparse\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/rag/ingestion/qdrant.py","lineNumber":211,"sourceCode":"  kwargs: dict[str, Any] = field(default_factory=dict)\n  dense_embedding_key: str = \"dense\"\n  sparse_embedding_key: str = \"sparse\"\n\n  def __post_init__(self):\n    if not self.collection_name:\n      raise ValueError(\"Collection name must be provided\")\n    if self.batch_size <= 0:\n      raise ValueError(\"Batch size must be a positive integer\")\n\n  def create_write_transform(self) -> beam.PTransform[EmbeddableItem, Any]:\n    return _QdrantWriteTransform(self)\n\n  def create_converter(\n      self,\n  ) -> Callable[[EmbeddableItem], \"models.PointStruct\"]:\n    def convert(item: EmbeddableItem) -> \"models.PointStruct\":\n      if item.dense_embedding is None and item.sparse_embedding is None:\n        raise ValueError(\n            \"EmbeddableItem must have at least one embedding (dense or sparse)\")\n      vector = {}\n      if item.dense_embedding is not None:\n        vector[self.dense_embedding_key] = item.dense_embedding\n      if item.sparse_embedding is not None:\n        sparse_indices, sparse_values = item.sparse_embedding\n        vector[self.sparse_embedding_key] = models.SparseVector(\n            indices=sparse_indices,\n            values=sparse_values,\n        )\n      id = (\n          int(item.id)\n          if isinstance(item.id, str) and item.id.isdigit() else item.id)\n      return models.PointStruct(\n          id=id,\n          vector=vector,\n          payload=item.metadata if item.metadata else None,\n      )","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/rag/ingestion/qdrant.py#L193-L229","documentation":"The converter built by create_converter() maps each EmbeddableItem to a Qdrant PointStruct. If an item has neither dense_embedding nor sparse_embedding, there is no vector to store, so the per-item conversion raises ValueError.","triggerScenarios":"Feeding items into the Qdrant write transform where the embedding step was skipped, the embedding model returned None, or items come from a source that doesn't populate embeddings (e.g. test fixtures or filtered records).","commonSituations":"Upstream EmbeddingsGeneration PTransform removed or failing silently; embedding API returning nulls for empty inputs; mixing pre-chunked items with items not yet embedded in one stream.","solutions":["Run the items through an embedding generation transform (e.g. the embedding config in the RAG pipeline) before the Qdrant sink","Filter out un-embedded items before writing","Check the embedding function/model for cases that return None (e.g. empty text)","Populate at least dense_embedding, or sparse_embedding as (indices, values) for sparse models"],"exampleFix":"// before\nitems | beam.Map(load_chunk) | qdrant_sink\n// after\nitems | beam.Map(load_chunk) | embed_transform | qdrant_sink","handlingStrategy":"try-catch","validationCode":"def is_embeddable(item) -> bool:\n    return item.dense_embedding is not None or item.sparse_embedding is not None\nitems = [i for i in items if is_embeddable(i)]","typeGuard":"def has_vector(item) -> bool:\n    return item.dense_embedding is not None or item.sparse_embedding is not None","tryCatchPattern":"try:\n    point = converter(item)\nexcept ValueError as e:\n    logging.warning(\"Skipping item without embedding: %s\", item)\n    return None","preventionTips":["Always place the embedding-generation transform before the Qdrant sink","Filter un-embedded items before writing","Check embedding functions for inputs that yield None (empty strings, blank pages)"],"tags":["python","qdrant","embeddings","data-validation"],"backgroundTag":"empty-required-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}