From d9eea9563ee7c26240121e440af4af7ce336db4b Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 3 May 2026 02:59:26 -0700 Subject: [PATCH 1/7] fix(files): align upload route image extensions with picker --- apps/sim/app/api/files/upload/route.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/api/files/upload/route.ts b/apps/sim/app/api/files/upload/route.ts index f328f5861e5..f5d553e2501 100644 --- a/apps/sim/app/api/files/upload/route.ts +++ b/apps/sim/app/api/files/upload/route.ts @@ -18,6 +18,7 @@ import { SUPPORTED_AUDIO_EXTENSIONS, SUPPORTED_CODE_EXTENSIONS, SUPPORTED_DOCUMENT_EXTENSIONS, + SUPPORTED_IMAGE_EXTENSIONS, SUPPORTED_VIDEO_EXTENSIONS, validateFileType, } from '@/lib/uploads/utils/validation' @@ -28,12 +29,10 @@ import { InvalidRequestError, } from '@/app/api/files/utils' -const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'] as const - const ALLOWED_EXTENSIONS = new Set([ ...SUPPORTED_DOCUMENT_EXTENSIONS, ...SUPPORTED_CODE_EXTENSIONS, - ...IMAGE_EXTENSIONS, + ...SUPPORTED_IMAGE_EXTENSIONS, ...SUPPORTED_AUDIO_EXTENSIONS, ...SUPPORTED_VIDEO_EXTENSIONS, ]) From 09618edb5b9984af7d097ae5624ca707458b357b Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 3 May 2026 03:02:42 -0700 Subject: [PATCH 2/7] fix(files): widen image mime mapping for chat/profile/logo uploads --- apps/sim/app/api/files/upload/route.ts | 4 +--- apps/sim/lib/uploads/utils/file-utils.ts | 7 +++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/api/files/upload/route.ts b/apps/sim/app/api/files/upload/route.ts index f5d553e2501..437ea4f009b 100644 --- a/apps/sim/app/api/files/upload/route.ts +++ b/apps/sim/app/api/files/upload/route.ts @@ -305,9 +305,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => { context === 'workspace-logos' ) { if (context !== 'copilot' && !isImageFileType(file.type)) { - throw new InvalidRequestError( - `Only image files (JPEG, PNG, GIF, WebP, SVG) are allowed for ${context} uploads` - ) + throw new InvalidRequestError(`Only image files are allowed for ${context} uploads`) } if (context === 'workspace-logos') { diff --git a/apps/sim/lib/uploads/utils/file-utils.ts b/apps/sim/lib/uploads/utils/file-utils.ts index 3dc0d75506b..b99b12bb6bf 100644 --- a/apps/sim/lib/uploads/utils/file-utils.ts +++ b/apps/sim/lib/uploads/utils/file-utils.ts @@ -33,6 +33,13 @@ export const MIME_TYPE_MAPPING: Record Date: Sun, 3 May 2026 03:07:52 -0700 Subject: [PATCH 3/7] fix(files): fall back to extension when MIME is generic for image-only uploads Co-Authored-By: Claude Opus 4.7 --- apps/sim/app/api/files/upload/route.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/api/files/upload/route.ts b/apps/sim/app/api/files/upload/route.ts index 437ea4f009b..a7d7e011002 100644 --- a/apps/sim/app/api/files/upload/route.ts +++ b/apps/sim/app/api/files/upload/route.ts @@ -304,8 +304,17 @@ export const POST = withRouteHandler(async (request: NextRequest) => { context === 'profile-pictures' || context === 'workspace-logos' ) { - if (context !== 'copilot' && !isImageFileType(file.type)) { - throw new InvalidRequestError(`Only image files are allowed for ${context} uploads`) + if (context !== 'copilot') { + const mimeType = file.type + const isGenericMime = !mimeType || mimeType === 'application/octet-stream' + const extension = originalName.split('.').pop()?.toLowerCase() ?? '' + const extensionIsImage = (SUPPORTED_IMAGE_EXTENSIONS as readonly string[]).includes( + extension + ) + const isImage = isGenericMime ? extensionIsImage : isImageFileType(mimeType) + if (!isImage) { + throw new InvalidRequestError(`Only image files are allowed for ${context} uploads`) + } } if (context === 'workspace-logos') { From 864aff36a7ba426717bda98c5b231afc93a6eefe Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 3 May 2026 03:10:31 -0700 Subject: [PATCH 4/7] fix(files): add new image extensions to EXTENSION_TO_MIME map Co-Authored-By: Claude Opus 4.7 --- apps/sim/lib/uploads/utils/file-utils.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/sim/lib/uploads/utils/file-utils.ts b/apps/sim/lib/uploads/utils/file-utils.ts index b99b12bb6bf..dd58fa73cb4 100644 --- a/apps/sim/lib/uploads/utils/file-utils.ts +++ b/apps/sim/lib/uploads/utils/file-utils.ts @@ -191,6 +191,13 @@ const EXTENSION_TO_MIME: Record = { gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml', + bmp: 'image/bmp', + tif: 'image/tiff', + tiff: 'image/tiff', + heic: 'image/heic', + heif: 'image/heif', + avif: 'image/avif', + ico: 'image/x-icon', // Documents pdf: 'application/pdf', From d2dcf3fc97d908a8ae92c40849b71c155c40d2fe Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 3 May 2026 03:13:27 -0700 Subject: [PATCH 5/7] fix(files): skip non-Claude image MIMEs in createFileContent Co-Authored-By: Claude Opus 4.7 --- apps/sim/lib/uploads/utils/file-utils.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/sim/lib/uploads/utils/file-utils.ts b/apps/sim/lib/uploads/utils/file-utils.ts index dd58fa73cb4..269faecf4d4 100644 --- a/apps/sim/lib/uploads/utils/file-utils.ts +++ b/apps/sim/lib/uploads/utils/file-utils.ts @@ -165,6 +165,10 @@ export function createFileContent(fileBuffer: Buffer, mimeType: string): Message return null } + if (contentType === 'image' && !CLAUDE_SUPPORTED_IMAGE_MIME_TYPES.has(mimeType.toLowerCase())) { + return null + } + return { type: contentType, source: { @@ -175,6 +179,13 @@ export function createFileContent(fileBuffer: Buffer, mimeType: string): Message } } +const CLAUDE_SUPPORTED_IMAGE_MIME_TYPES = new Set([ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/webp', +]) + /** * Extract file extension from filename */ From b92a51bc16e4e10f83a7d6eed18edd271ef13a37 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 3 May 2026 03:21:02 -0700 Subject: [PATCH 6/7] fix(files): resolve content type for image-only contexts when MIME is generic Co-Authored-By: Claude Opus 4.7 --- apps/sim/app/api/files/upload/route.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/api/files/upload/route.ts b/apps/sim/app/api/files/upload/route.ts index a7d7e011002..9a3880639e7 100644 --- a/apps/sim/app/api/files/upload/route.ts +++ b/apps/sim/app/api/files/upload/route.ts @@ -13,7 +13,7 @@ import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { captureServerEvent } from '@/lib/posthog/server' import type { StorageContext } from '@/lib/uploads/config' import { generateWorkspaceFileKey } from '@/lib/uploads/contexts/workspace/workspace-file-manager' -import { isImageFileType } from '@/lib/uploads/utils/file-utils' +import { isImageFileType, resolveFileType } from '@/lib/uploads/utils/file-utils' import { SUPPORTED_AUDIO_EXTENSIONS, SUPPORTED_CODE_EXTENSIONS, @@ -350,6 +350,8 @@ export const POST = withRouteHandler(async (request: NextRequest) => { logger.info(`Uploading ${context} file: ${originalName}`) + const resolvedContentType = resolveFileType({ type: file.type, name: originalName }) + const timestamp = Date.now() const safeFileName = sanitizeFileName(originalName) const storageKey = `${context}/${timestamp}-${safeFileName}` @@ -368,7 +370,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => { const fileInfo = await storageService.uploadFile({ file: buffer, fileName: storageKey, - contentType: file.type, + contentType: resolvedContentType, context, preserveKey: true, customKey: storageKey, @@ -385,7 +387,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => { key: fileInfo.key, name: originalName, size: buffer.length, - type: file.type, + type: resolvedContentType, }, directUploadSupported: false, } From 6abf6c29d9e130f04ef73078e26a553b713e5e27 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 3 May 2026 03:28:21 -0700 Subject: [PATCH 7/7] fix(files): cover image/jpg in Claude gate, reverse MIME map, audit metadata Co-Authored-By: Claude Opus 4.7 --- apps/sim/app/api/files/upload/route.ts | 2 +- apps/sim/lib/uploads/utils/file-utils.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/sim/app/api/files/upload/route.ts b/apps/sim/app/api/files/upload/route.ts index 9a3880639e7..424935f5941 100644 --- a/apps/sim/app/api/files/upload/route.ts +++ b/apps/sim/app/api/files/upload/route.ts @@ -408,7 +408,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => { fileName: originalName, fileKey: fileInfo.key, fileSize: buffer.length, - fileType: file.type, + fileType: resolvedContentType, }, request, }) diff --git a/apps/sim/lib/uploads/utils/file-utils.ts b/apps/sim/lib/uploads/utils/file-utils.ts index 269faecf4d4..edb601b9470 100644 --- a/apps/sim/lib/uploads/utils/file-utils.ts +++ b/apps/sim/lib/uploads/utils/file-utils.ts @@ -181,6 +181,7 @@ export function createFileContent(fileBuffer: Buffer, mimeType: string): Message const CLAUDE_SUPPORTED_IMAGE_MIME_TYPES = new Set([ 'image/jpeg', + 'image/jpg', 'image/png', 'image/gif', 'image/webp', @@ -364,6 +365,13 @@ const MIME_TO_EXTENSION: Record = { 'image/gif': 'gif', 'image/webp': 'webp', 'image/svg+xml': 'svg', + 'image/bmp': 'bmp', + 'image/tiff': 'tiff', + 'image/heic': 'heic', + 'image/heif': 'heif', + 'image/avif': 'avif', + 'image/x-icon': 'ico', + 'image/vnd.microsoft.icon': 'ico', // Documents 'application/pdf': 'pdf',