Fix: Avatar Upload — Web MIME Type / Extension Extraction

Branch: fix/avatar-upload-web-mime-type Merged into: develop Date: 2026-03-17


Summary

Fixed EncodingError: The source image cannot be decoded on Flutter Web when uploading a profile avatar. Root cause: using image.path to extract the file extension, which is a blob URL on web and yields a garbage extension and MIME type.


Error

[Flutter] EncodingError: The source image cannot be decoded.

Observed on: Chrome 145 / Windows / Flutter Web


Root Cause

In edit_profile_screen.dart, the upload code was:

final ext = image.path.split('.').last;
final storagePath = 'avatars/$userId.$ext';
// contentType: 'image/$ext'

On Flutter Web, image.path is a blob URL:

blob:https://myapp.example.com/f3a47c2b-1234-...

split('.').last on this URL returns a meaningless string (the tail of the UUID or domain), resulting in:

  • storagePath = 'avatars/user-id.com/...' — malformed path
  • contentType = 'image/com/...' — invalid MIME type

Supabase would still store the bytes but with wrong metadata. The browser then receives a response with the wrong Content-Type header and throws EncodingError when trying to decode it as an image.


Fix

In lib/features/profile/screens/edit_profile_screen.dart:

// BEFORE — breaks on web
final ext = image.path.split('.').last;
 
// AFTER — works on all platforms
final rawExt = image.name.contains('.')
    ? image.name.split('.').last.toLowerCase()
    : 'jpg';
// Normalize: MIME spec requires 'image/jpeg', not 'image/jpg'
final mimeType = rawExt == 'jpg' ? 'image/jpeg' : 'image/$rawExt';
final storagePath = 'avatars/$userId.$rawExt';

Key differences

PropertyNative (iOS/Android)Flutter Web
image.pathReal filesystem path (e.g., /tmp/IMG_001.jpg)Blob URL (blob:https://...)
image.nameFilename (e.g., IMG_001.jpg)Filename (e.g., photo.jpg)

Always use image.name to extract the extension — it works correctly on all platforms.

MIME type normalization

image/jpg is not a valid MIME type. The correct type for JPEG images is image/jpeg. Browsers and servers may reject files served with Content-Type: image/jpg.


Errors Resolved

  • EncodingError: The source image cannot be decoded (×1, Chrome/Web)