From 9517864603cae252d28a608a7afbc490b42976d6 Mon Sep 17 00:00:00 2001 From: Matteo Celani <26189482+matteocelani@users.noreply.github.com> Date: Fri, 10 Apr 2026 23:03:51 +0200 Subject: [PATCH] app/ui: re-validate image attachments when selected model changes (#15272) --- app/ui/app/src/components/ChatForm.tsx | 39 +++++++++++++++------ app/ui/app/src/utils/fileValidation.test.ts | 8 +++-- app/ui/app/src/utils/fileValidation.ts | 5 --- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/app/ui/app/src/components/ChatForm.tsx b/app/ui/app/src/components/ChatForm.tsx index 78e50ffd1..b0ae1af74 100644 --- a/app/ui/app/src/components/ChatForm.tsx +++ b/app/ui/app/src/components/ChatForm.tsx @@ -480,13 +480,15 @@ function ChatForm({ return; } - // Prepare attachments for submission - const attachmentsToSend: FileAttachment[] = message.attachments.map( - (att) => ({ + // Prepare attachments for submission, excluding unsupported images + const attachmentsToSend: FileAttachment[] = message.attachments + .filter( + (att) => hasVisionCapability || !isImageFile(att.filename), + ) + .map((att) => ({ filename: att.filename, data: att.data || new Uint8Array(0), // Empty data for existing files - }), - ); + })); const useWebSearch = supportsWebSearch && webSearchEnabled && !cloudDisabled; @@ -736,10 +738,17 @@ function ChatForm({ )} {(message.attachments.length > 0 || message.fileErrors.length > 0) && (
- {message.attachments.map((attachment, index) => ( + {message.attachments.map((attachment, index) => { + const isUnsupportedImage = + !hasVisionCapability && isImageFile(attachment.filename); + return (
{isImageFile(attachment.filename) ? ( )} - - {attachment.filename} - +
+ + {attachment.filename} + + {isUnsupportedImage && ( + + This model does not support images + + )} +
- ))} + ); + })} {message.fileErrors.map((fileError, index) => (
{ expect(result.valid).toBe(true); }); - it("should reject WebP images when vision capability is disabled", () => { + it("should accept images regardless of vision capability", () => { + // Vision capability check is handled at the UI layer (ChatForm), + // not at validation time, so users can switch models without + // needing to re-upload files. const file = createMockFile("test.webp", 1024, "image/webp"); const result = validateFile(file, { hasVisionCapability: false, }); - expect(result.valid).toBe(false); - expect(result.error).toBe("This model does not support images"); + expect(result.valid).toBe(true); }); it("should accept PNG images when vision capability is enabled", () => { diff --git a/app/ui/app/src/utils/fileValidation.ts b/app/ui/app/src/utils/fileValidation.ts index 047aa9984..d7a01a1c6 100644 --- a/app/ui/app/src/utils/fileValidation.ts +++ b/app/ui/app/src/utils/fileValidation.ts @@ -63,7 +63,6 @@ export function validateFile( const { maxFileSize = 10, allowedExtensions = [...TEXT_FILE_EXTENSIONS, ...IMAGE_EXTENSIONS], - hasVisionCapability = false, customValidator, } = options; @@ -83,10 +82,6 @@ export function validateFile( return { valid: false, error: "File type not supported" }; } - if (IMAGE_EXTENSIONS.includes(fileExtension) && !hasVisionCapability) { - return { valid: false, error: "This model does not support images" }; - } - // File size validation if (file.size > MAX_FILE_SIZE) { return { valid: false, error: "File too large" };