{"record":{"id":"d4c370e9a5ab3f84","repo":"oobabooga/textgen","slug":"messages-missing-image-url-in-content-item","errorCode":null,"errorMessage":"messages: missing image_url in content item","messagePattern":"messages: missing image_url in content item","errorType":"exception","errorClass":"InvalidRequestError","httpStatus":400,"severity":"error","filePath":"modules/api/completions.py","lineNumber":521,"sourceCode":"        content = m.get('content')\n        if content is None:\n            # OpenAI allows content: null on assistant messages when tool_calls is present\n            if m['role'] == 'assistant' and m.get('tool_calls'):\n                m['content'] = ''\n            else:\n                raise InvalidRequestError(message=\"messages: missing content\", param='messages')\n\n        # Validate multimodal content structure\n        if isinstance(content, list):\n            for item in content:\n                if not isinstance(item, dict) or 'type' not in item:\n                    raise InvalidRequestError(message=\"messages: invalid content item format\", param='messages')\n                if item['type'] not in ['text', 'image_url']:\n                    raise InvalidRequestError(message=\"messages: unsupported content type\", param='messages')\n                if item['type'] == 'text' and 'text' not in item:\n                    raise InvalidRequestError(message=\"messages: missing text in content item\", param='messages')\n                if item['type'] == 'image_url' and ('image_url' not in item or 'url' not in item['image_url']):\n                    raise InvalidRequestError(message=\"messages: missing image_url in content item\", param='messages')\n\n    # Chat Completions\n    object_type = 'chat.completion' if not stream else 'chat.completion.chunk'\n    created_time = int(time.time())\n    cmpl_id = \"chatcmpl-%d\" % (int(time.time() * 1000000000))\n    resp_list = 'data' if is_legacy else 'choices'\n\n    # generation parameters\n    generate_params = process_parameters(body, is_legacy=is_legacy)\n    if stop_event is not None:\n        generate_params['stop_event'] = stop_event\n    continue_ = body['continue_']\n\n    # Instruction template\n    if body['instruction_template_str']:\n        instruction_template_str = body['instruction_template_str']\n    elif body['instruction_template']:\n        instruction_template = body['instruction_template']","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/oobabooga/textgen/blob/ed888c71f221df552750e1834b3654abab8ae345/modules/api/completions.py#L503-L539","documentation":"A content item with type 'image_url' must contain an 'image_url' object which itself contains a 'url' key. Missing either raises InvalidRequestError (400, param='messages'). The url may be an http(s) link or a base64 data URI.","triggerScenarios":"POST /v1/chat/completions with {\"type\": \"image_url\"} alone, {\"type\": \"image_url\", \"url\": u} (url at wrong level), or {\"type\": \"image_url\", \"image_url\": {}} (no url).","commonSituations":"Flattening the nested structure by mistake; sending {'image_url': {'url': None}} from a pipeline where image loading failed; adapting from a schema that puts the URL at item top level.","solutions":["Use the full nesting: {\"type\": \"image_url\", \"image_url\": {\"url\": \"https://...\" or \"data:image/jpeg;base64,...\"}}.","Check the URL is non-empty and a valid string before appending the item.","For local files, base64-encode into a data URI since the server fetches URLs server-side."],"exampleFix":"# before\n{\"type\": \"image_url\", \"url\": \"https://example.com/cat.png\"}\n\n# after\n{\"type\": \"image_url\", \"image_url\": {\"url\": \"https://example.com/cat.png\"}}","handlingStrategy":"validation","validationCode":"def image_item(url: str) -> dict:\n    if not url or not isinstance(url, str):\n        raise ValueError('image url required')\n    return {'type': 'image_url', 'image_url': {'url': url}}","typeGuard":"def is_valid_image_item(i) -> bool:\n    return (isinstance(i, dict) and i.get('type') == 'image_url'\n            and isinstance(i.get('image_url'), dict)\n            and isinstance(i['image_url'].get('url'), str) and bool(i['image_url']['url']))","tryCatchPattern":"try:\n    resp = client.chat.completions.create(model=m, messages=msgs)\nexcept openai.BadRequestError as e:\n    if 'missing image_url' in str(e):\n        raise ValueError('image content item missing nested image_url.url')\n    raise","preventionTips":["Always nest: {'type':'image_url','image_url':{'url': ...}}; never flatten.","Base64 local files into data: URIs; the server fetches URLs itself.","Fail fast at build time if the image source produced an empty URL."],"tags":["openai-api","chat-completions","multimodal","vision","validation"],"backgroundTag":null,"analyzedSha":"ed888c71f221df552750e1834b3654abab8ae345","analyzedAt":"2026-08-15T05:24:21.000Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}