From 5ac3930c987fe87e6831cc94cde5b0b1499bdd40 Mon Sep 17 00:00:00 2001 From: DrMelone <27028174+Classic298@users.noreply.github.com> Date: Sun, 12 Apr 2026 22:55:29 +0200 Subject: [PATCH] fix: strict image source validation, catch all conversion errors as 400 --- backend/open_webui/main.py | 3 ++- backend/open_webui/utils/anthropic.py | 27 +++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 73d0c075e1..6b69a7f748 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1956,7 +1956,8 @@ async def generate_messages( try: openai_payload = convert_anthropic_to_openai_payload(form_data) - except (ValueError, NotImplementedError) as e: + except Exception as e: + log.debug('Anthropic payload conversion failed: %s', e) raise HTTPException(status_code=400, detail=str(e)) # Route through the existing chat_completion handler diff --git a/backend/open_webui/utils/anthropic.py b/backend/open_webui/utils/anthropic.py index 85fd347906..cc5cb32532 100644 --- a/backend/open_webui/utils/anthropic.py +++ b/backend/open_webui/utils/anthropic.py @@ -92,13 +92,18 @@ async def get_anthropic_models(url: str, key: str, user: UserModel = None) -> di def _convert_anthropic_image_source(source: dict) -> str: """Convert an Anthropic image source block to an OpenAI-compatible image URL.""" - if source.get('type') == 'base64': + if not isinstance(source, dict): + raise ValueError( + f'Expected dict for image source, got {type(source).__name__}' + ) + source_type = source.get('type') + if source_type == 'base64': media_type = source.get('media_type', 'image/png') data = source.get('data', '') return f'data:{media_type};base64,{data}' - elif source.get('type') == 'url': + elif source_type == 'url': return source.get('url', '') - return '' + raise ValueError(f'Unsupported image source type: {source_type!r}') def convert_anthropic_to_openai_payload(anthropic_payload: dict) -> dict: @@ -157,13 +162,12 @@ def convert_anthropic_to_openai_payload(anthropic_payload: dict) -> dict: ) elif block_type == 'image': url = _convert_anthropic_image_source(block.get('source', {})) - if url: - openai_content.append( - { - 'type': 'image_url', - 'image_url': {'url': url}, - } - ) + openai_content.append( + { + 'type': 'image_url', + 'image_url': {'url': url}, + } + ) elif block_type == 'tool_use': tool_calls.append( { @@ -196,8 +200,7 @@ def convert_anthropic_to_openai_payload(anthropic_payload: dict) -> dict: url = _convert_anthropic_image_source( tc.get('source', {}) ) - if url: - image_urls.append(url) + image_urls.append(url) elif tc_type in ('search_result', 'document'): raise NotImplementedError( f'Anthropic tool_result content type '