apache/beam · error · ValueError

Expected image content in {type(item).__name__} {item.id}, g

Error message

Expected image content in {type(item).__name__} {item.id}, got None

What it means

_extract_images in apache_beam.ml.rag/embeddings huggingface module raises this ValueError when an EmbeddableItem in the batch has no content.image (None). The helper loads image bytes/paths for HuggingfaceImageEmbeddings, which requires actual image data per item, so image-less items are rejected with a message naming the item's type and id. It runs on workers inside the batching path at pipeline runtime.

Source

Thrown at sdks/python/apache_beam/ml/rag/embeddings/huggingface.py:109

      self, **kwargs
  ) -> beam.PTransform[beam.PCollection[EmbeddableItem],
                       beam.PCollection[EmbeddableItem]]:
    """Returns PTransform that uses the RAG adapter."""
    return RunInference(
        model_handler=_TextEmbeddingHandler(self),
        inference_args=self.inference_args).with_output_types(EmbeddableItem)


def _extract_images(items: Sequence[EmbeddableItem]) -> list:
  """Extract images from items and convert to PIL.Image objects.

  Supports raw bytes, local file paths, and remote URIs
  (e.g. gs://, s3://) via Beam's FileSystems.
  """
  images = []
  for item in items:
    if not item.content.image:
      raise ValueError(
          "Expected image content in "
          f"{type(item).__name__} {item.id}, "
          "got None")
    img_data = item.content.image
    if isinstance(img_data, bytes):
      img = PILImage.open(io.BytesIO(img_data))
    else:
      with FileSystems.open(img_data, 'rb') as f:
        img = PILImage.open(f)
        img.load()
    images.append(img.convert('RGB'))
  return images


def _create_hf_image_adapter(
) -> EmbeddingTypeAdapter[EmbeddableItem, EmbeddableItem]:
  """Creates adapter for HuggingFace image embedding.

View on GitHub (pinned to 12126d8942)

Solutions

  1. Filter items without image data before the transform: beam.Filter(lambda x: x.content.image).
  2. Fix the upstream step so content.image is populated with bytes, a local path, or a remote URI (gs://, s3://).
  3. Use the text embeddings manager for text-only items.
  4. Use the reported item.id to trace the bad record to its origin.

Example fix

// before
embedded = pcoll | image_embedder

// after
embedded = (pcoll
    | beam.Filter(lambda item: item.content.image)
    | image_embedder)
Defensive patterns

Strategy: validation

Validate before calling

import apache_beam as beam

def filter_items_without_image(pcoll):
    return pcoll | 'DropEmptyImage' >> beam.Filter(
        lambda item: bool(item.content and item.content.image))

Type guard

def has_image(item) -> bool:
    content = getattr(item, 'content', None)
    return bool(content is not None and getattr(content, 'image', None))

Try / catch

try:
    result = pcoll | image_embedder
except ValueError as e:
    # e.g. 'Expected image content in EmbeddableItem <id>, got None'
    logging.error('Embedding input missing image: %s', e)
    raise

Prevention

When it happens

Trigger: Passing items whose content.image was never populated (e.g. records built for text embedding, or source rows with null image columns/URIs) through HuggingfaceImageEmbeddings; upstream file reads silently failing and leaving image=None; mixing text and image items in one PCollection.

Common situations: Datasets with missing/placeholder image references; a key rename in the record-building step (image bytes stored under a different field); sending text documents to an image embeddings pipeline by mistake.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/e0d82712590c8558. Report an issue: GitHub.