xai-org/x-algorithm · error · ValueError

Invalid message type: {type(message)=}

Error message

Invalid message type: {type(message)=}

What it means

VisionSampler._get_sample_request only accepts messages that are bytes (treated as raw image data) or str (treated as text). Any other Python object hits the else branch, logs 'unexpected message', and raises ValueError. It is a strict input-type contract enforced per message in the inputs list.

Source

Thrown at grox/libs/grok_sampler/vision_sampler.py:34

        nucleus_p = kwargs.get("nucleus_p", 0.95)
        temperature = kwargs.get("temperature", self.model_config.temperature)
        rng_seed = kwargs.get("rng_seed", None)
        json_schema = kwargs.get("json_schema", None)
        structural_tag = kwargs.get("structural_tag", None)
        structural_pattern = kwargs.get("structural_pattern", None)
        structural_pattern_v2 = kwargs.get("structural_pattern_v2", None)
        ebnf = kwargs.get("ebnf", None)
        priority = kwargs.get("priority", self.model_config.priority)

        inputs: list[PromptInput] = []
        for message in query:
            if isinstance(message, bytes):
                inputs.append(PromptInput(image=message))
            elif isinstance(message, str):
                inputs.append(PromptInput(text=message))
            else:
                logger.error(f"unexpected message: {message}")
                raise ValueError(f"Invalid message type: {type(message)=}")

        return SampleTextRequest(
            inputs=inputs,
            output_probs=output_logits,
            return_tokens=output_logits,
            conversation_id=conversation_id,
            settings=SampleSettings(
                max_len=max_resp_len,
                stop_strings=[separator],
                rng_seed=rng_seed,
                nucleus_p=nucleus_p,
                temperature=temperature,
            ),
            json_schema=json_schema,
            structural_tag=structural_tag,
            structural_pattern=structural_pattern,
            structural_pattern_v2=structural_pattern_v2,
            ebnf=ebnf,

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Convert the message to bytes: open(path,'rb').read() or image.tobytes() after encoding to JPEG/PNG via io.BytesIO.
  2. If it is text-only input, ensure it is a plain str (not a dict like {'text': ...}).
  3. Add a pre-flight normalization step that maps Path->bytes and PIL.Image->encoded bytes before calling the sampler.

Example fix

# before
await vision_sampler.sample(messages=[PIL.Image.open('cat.png')])  # ValueError

# after
buf = io.BytesIO()
PIL.Image.open('cat.png').save(buf, format='PNG')
await vision_sampler.sample(messages=[buf.getvalue()])
Defensive patterns

Strategy: type-guard

Validate before calling

def to_input(msg):
    if isinstance(msg, (str, bytes)):
        return msg
    if isinstance(msg, os.PathLike):
        return open(msg, 'rb').read()
    if hasattr(msg, 'save'):  # PIL Image
        buf = io.BytesIO(); msg.save(buf, format='PNG'); return buf.getvalue()
    raise TypeError(f'unsupported message: {type(msg)}')
messages = [to_input(m) for m in messages]

Type guard

def is_valid_message(m: object) -> bool:
    return isinstance(m, (str, bytes))

Try / catch

try:
    req = sampler._get_sample_request(messages)
except ValueError as e:
    if 'Invalid message type' in str(e):
        logger.error('normalize messages to str/bytes before sampling')
    raise

Prevention

When it happens

Trigger: Calling the vision sampling API with a message that is neither str nor bytes — e.g. a dict, pathlib.Path, PIL.Image.Image, numpy array, or None inside the messages/conversation payload.

Common situations: Passing a file path (Path object) instead of reading the file bytes; passing a PIL/numpy image without encoding to PNG/JPEG bytes first; passing a list or dict message format from another library's schema; a None sneaking in from an upstream optional field.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/51b1c7c167a78dfd. Report an issue: GitHub.