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
- Convert the message to bytes: open(path,'rb').read() or image.tobytes() after encoding to JPEG/PNG via io.BytesIO.
- If it is text-only input, ensure it is a plain str (not a dict like {'text': ...}).
- 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
- Encode images to bytes at ingestion boundaries
- Keep message payloads typed as str|bytes in your dataclasses
- Log type(message) for unexpected inputs in upstream pipelines
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
- spt must be a bool when provided
- `axis` should be an int, slice or iterable of ints.
- execution_devices must be a list of xc.Device. Got: {executi
- Unsupported type: {type(self.jitted)}.
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/51b1c7c167a78dfd.
Report an issue: GitHub.