{"record":{"id":"51b1c7c167a78dfd","repo":"xai-org/x-algorithm","slug":"invalid-message-type-type-message","errorCode":null,"errorMessage":"Invalid message type: {type(message)=}","messagePattern":"Invalid message type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"grox/libs/grok_sampler/vision_sampler.py","lineNumber":34,"sourceCode":"        nucleus_p = kwargs.get(\"nucleus_p\", 0.95)\n        temperature = kwargs.get(\"temperature\", self.model_config.temperature)\n        rng_seed = kwargs.get(\"rng_seed\", None)\n        json_schema = kwargs.get(\"json_schema\", None)\n        structural_tag = kwargs.get(\"structural_tag\", None)\n        structural_pattern = kwargs.get(\"structural_pattern\", None)\n        structural_pattern_v2 = kwargs.get(\"structural_pattern_v2\", None)\n        ebnf = kwargs.get(\"ebnf\", None)\n        priority = kwargs.get(\"priority\", self.model_config.priority)\n\n        inputs: list[PromptInput] = []\n        for message in query:\n            if isinstance(message, bytes):\n                inputs.append(PromptInput(image=message))\n            elif isinstance(message, str):\n                inputs.append(PromptInput(text=message))\n            else:\n                logger.error(f\"unexpected message: {message}\")\n                raise ValueError(f\"Invalid message type: {type(message)=}\")\n\n        return SampleTextRequest(\n            inputs=inputs,\n            output_probs=output_logits,\n            return_tokens=output_logits,\n            conversation_id=conversation_id,\n            settings=SampleSettings(\n                max_len=max_resp_len,\n                stop_strings=[separator],\n                rng_seed=rng_seed,\n                nucleus_p=nucleus_p,\n                temperature=temperature,\n            ),\n            json_schema=json_schema,\n            structural_tag=structural_tag,\n            structural_pattern=structural_pattern,\n            structural_pattern_v2=structural_pattern_v2,\n            ebnf=ebnf,","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/grox/libs/grok_sampler/vision_sampler.py#L16-L52","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nawait vision_sampler.sample(messages=[PIL.Image.open('cat.png')])  # ValueError\n\n# after\nbuf = io.BytesIO()\nPIL.Image.open('cat.png').save(buf, format='PNG')\nawait vision_sampler.sample(messages=[buf.getvalue()])","handlingStrategy":"type-guard","validationCode":"def to_input(msg):\n    if isinstance(msg, (str, bytes)):\n        return msg\n    if isinstance(msg, os.PathLike):\n        return open(msg, 'rb').read()\n    if hasattr(msg, 'save'):  # PIL Image\n        buf = io.BytesIO(); msg.save(buf, format='PNG'); return buf.getvalue()\n    raise TypeError(f'unsupported message: {type(msg)}')\nmessages = [to_input(m) for m in messages]","typeGuard":"def is_valid_message(m: object) -> bool:\n    return isinstance(m, (str, bytes))","tryCatchPattern":"try:\n    req = sampler._get_sample_request(messages)\nexcept ValueError as e:\n    if 'Invalid message type' in str(e):\n        logger.error('normalize messages to str/bytes before sampling')\n    raise","preventionTips":["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"],"tags":["type-validation","input-contract","vision","images"],"backgroundTag":"invalid-input-type","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}