chroma-core/chroma · error · ValueError

Instructor only supports text documents, not images

Error message

Instructor only supports text documents, not images

What it means

Instructor's INSTRUCTOR model is text-only, so InstructorEmbeddingFunction.__call__ validates that every item in input is a str and raises this ValueError if any item is not. Chroma's Documents type also permits image inputs (PIL images or numpy arrays) for multimodal EFs, so this guard rejects image payloads early instead of letting the model fail obscurely.

Source

Thrown at chromadb/utils/embedding_functions/instructor_embedding_function.py:56

        self.model_name = model_name
        self.device = device
        self.instruction = instruction

        self._model = INSTRUCTOR(model_name_or_path=model_name, device=device)

    def __call__(self, input: Documents) -> Embeddings:
        """
        Generate embeddings for the given documents.

        Args:
            input: Documents or images to generate embeddings for.

        Returns:
            Embeddings for the documents.
        """
        # Instructor only works with text documents
        if not all(isinstance(item, str) for item in input):
            raise ValueError("Instructor only supports text documents, not images")

        if self.instruction is None:
            embeddings = self._model.encode(input, convert_to_numpy=True)
        else:
            texts_with_instructions = [[self.instruction, text] for text in input]
            embeddings = self._model.encode(
                texts_with_instructions, convert_to_numpy=True
            )

        # Convert to numpy arrays
        return [np.array(embedding, dtype=np.float32) for embedding in embeddings]

    @staticmethod
    def name() -> str:
        return "instructor"

    def default_space(self) -> Space:
        return "cosine"

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Pass only strings: decode bytes to str, str() scalars, and drop image entries before calling the EF
  2. If images must be embedded, switch the collection to a multimodal EF such as JinaEmbeddingFunction (numpy-array image support)
  3. Add an isinstance check in your ingestion code so image payloads are routed to an image-capable pipeline

Example fix

# before
docs = ["a caption", np.asarray(image_rgb, dtype=np.uint8)]
collection.add(documents=docs, ids=["1", "2"])  # ValueError

# after
docs = [d if isinstance(d, str) else str(d) for d in docs]  # or route images to a multimodal EF
collection.add(documents=docs, ids=["1", "2"])
Defensive patterns

Strategy: type-guard

Validate before calling

docs = ["a", b"b", np.zeros((4, 4), dtype=np.uint8)]
if not all(isinstance(d, str) for d in docs):
    raise ValueError("Instructor EF accepts text documents only")
collection.add(documents=[d for d in docs if isinstance(d, str)], ids=ids)

Type guard

from typing import List

def is_all_text(docs: List[object]) -> bool:
    """Narrow Documents to text-only, as required by Instructor EF."""
    return len(docs) > 0 and all(isinstance(d, str) for d in docs)

Try / catch

try:
    vectors = ef(docs)
except ValueError as e:
    if "only supports text" in str(e):
        docs = [d for d in docs if isinstance(d, str)]  # or reroute to multimodal EF
        vectors = ef(docs)
    else:
        raise

Prevention

When it happens

Trigger: collection.add(documents=[img_array]) or ef([np.array(...), "text"]) with the Instructor EF configured; mixing a multimodal ingestion pipeline (built for e.g. Jina) with an Instructor EF; passing bytes or PIL.Image.Image objects as documents.

Common situations: Reusing one ingestion pipeline across collections with different EFs; upgrading a pipeline to multimodal data while the collection was created with InstructorEmbeddingFunction; documents deserialized from binary stores (bytes instead of str).

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/575956e1b8663ceb. Report an issue: GitHub.