{"record":{"id":"aeb2eb1ad77440ac","repo":"HKUDS/DeepTutor","slug":"openai-compatible-embedding-model-model-does-n","errorCode":null,"errorMessage":"OpenAI-compatible embedding model '{model}' does not support multimodal `contents`.","messagePattern":"OpenAI-compatible embedding model '(.+?)' does not support multimodal `contents`\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/embedding/adapters/openai_compatible.py","lineNumber":184,"sourceCode":"            dimension=self.dimensions or 1,\n            send_dimensions=self.send_dimensions,\n        )\n\n    async def embed(self, request: EmbeddingRequest) -> EmbeddingResponse:\n        import asyncio\n\n        headers = {\"Content-Type\": \"application/json\"}\n        api_key = self._auth_api_key()\n        self._set_auth_header(headers, api_key)\n        headers.update({str(k): str(v) for k, v in self.extra_headers.items()})\n\n        # Multimodal: pass `contents` through as `input` only for model names\n        # that clearly advertise image/vision embedding support. This prevents\n        # image indexing from accidentally hitting ordinary text-embedding\n        # models just because the provider family has some multimodal models.\n        model = request.model or self.model\n        if request.contents and not looks_like_multimodal_embedding_model(model):\n            raise ValueError(\n                f\"OpenAI-compatible embedding model '{model}' does not support \"\n                \"multimodal `contents`.\"\n            )\n        input_payload: Any = request.contents if request.contents else request.texts\n\n        payload = {\n            \"input\": input_payload,\n            \"model\": model,\n        }\n        # `encoding_format` is opt-in: omit it by default (request default is\n        # None) because several OpenAI-compatible gateways (e.g. SiliconFlow)\n        # reject the param with HTTP 400. Only forward an explicit choice.\n        # Do not add a default here for the gateways that require the param —\n        # that trades #934 for #651. The retry below recovers those from the\n        # provider's own refusal, leaving every working config untouched.\n        if request.encoding_format:\n            payload[\"encoding_format\"] = request.encoding_format\n","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/embedding/adapters/openai_compatible.py#L166-L202","documentation":"embed() was called with multimodal `contents` (image inputs) while the configured model name does not look like a multimodal embedding model. The adapter refuses to forward image payloads to ordinary text-embedding models, which would either fail cryptically or silently embed garbage.","triggerScenarios":"EmbeddingRequest.contents is non-empty AND looks_like_multimodal_embedding_model(model) is False — e.g. indexing images against text-embedding-3-small or a Qwen text-embedding model.","commonSituations":"Image/PDF indexing pipeline accidentally wired to a text-only embedding binding; model name lacks vision/VL/multimodal markers (e.g. 'jina-clip', 'Qwen3-VL-Embedding' pass; 'bge-m3' fails).","solutions":["Switch the KB's embedding binding to a multimodal embedding model (name containing clip/vl/image/multimodal markers)","Or keep the text model and index only text — do not pass contents","If the model genuinely is multimodal but named without recognized markers, rename/alias it so the heuristic matches or route via a multimodal-capable provider (cohere, aliyun)"],"exampleFix":"# before\nmodel = \"text-embedding-3-small\"  # + request.contents -> raises\n# after\nmodel = \"Qwen3-VL-Embedding\"  # recognized as multimodal, contents forwarded as input","handlingStrategy":"validation","validationCode":"from deeptutor.services.embedding.adapters.base import looks_like_multimodal_embedding_model\n\ndef can_embed_contents(adapter, model):\n    return looks_like_multimodal_embedding_model(model or adapter.model)","typeGuard":"def supports_multimodal_contents(model: str) -> bool:\n    return looks_like_multimodal_embedding_model(model)","tryCatchPattern":"null","preventionTips":["Before image indexing, check the model name carries clip/vl/multimodal markers","Keep separate KB bindings for text-only and multimodal embedding models"],"tags":["embeddings","multimodal","input-validation","model-mismatch"],"backgroundTag":"model-does-not-support-input-modality","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}