jamiepine/voicebox · warning · ValueError
File size exceeds maximum of 5MB
Error message
File size exceeds maximum of 5MB
What it means
Returned by validate_image() in backend/utils/images.py when path.stat().st_size exceeds MAX_FILE_SIZE (5 * 1024 * 1024 bytes). upload_avatar() calls validate_image and re-raises the returned message as a ValueError. The cap protects avatar storage and downstream resize processing from oversized inputs.
Source
Thrown at backend/services/profiles.py:649
) -> VoiceProfileResponse:
"""
Upload and process avatar image for a profile.
Args:
profile_id: Profile ID
image_path: Path to uploaded image file
db: Database session
Returns:
Updated profile
"""
profile = db.query(DBVoiceProfile).filter_by(id=profile_id).first()
if not profile:
raise ValueError(f"Profile {profile_id} not found")
is_valid, error_msg = validate_image(image_path)
if not is_valid:
raise ValueError(error_msg)
if profile.avatar_path:
old_avatar = config.resolve_storage_path(profile.avatar_path)
if old_avatar is not None and old_avatar.exists():
old_avatar.unlink()
# Determine file extension from uploaded file
from PIL import Image
with Image.open(image_path) as img:
# Normalize JPEG variants (MPO is multi-picture format from some cameras)
img_format = img.format
if img_format in ("MPO", "JPG"):
img_format = "JPEG"
ext_map = {"PNG": ".png", "JPEG": ".jpg", "WEBP": ".webp"}
ext = ext_map.get(img_format, ".png")
View on GitHub (pinned to 51f49dea19)
Solutions
- Compress or downscale the image to under 5 MB before uploading (export at <=1024px, JPEG quality ~85).
- Raise the client-side size check so users are warned before the request.
- If business needs warrant, increase MAX_FILE_SIZE in backend/utils/images.py and adjust any reverse-proxy body-size limit.
- Convert HEIC/RAW sources to optimized JPEG first.
Example fix
// before: uploading a 12MB JPEG straight from the camera
// after: resize/compress client-side to <=5MB
from PIL import Image
img = Image.open('avatar.jpg')
img.thumbnail((1024, 1024))
img.save('avatar_small.jpg', 'JPEG', quality=85) // now well under 5MB Defensive patterns
Strategy: validation
Validate before calling
from backend.utils.images import MAX_FILE_SIZE
from pathlib import Path
if Path(image_path).stat().st_size > MAX_FILE_SIZE:
raise HTTPException(413, f"Avatar exceeds {MAX_FILE_SIZE // (1024*1024)}MB") Try / catch
try:
profile = await upload_avatar(profile_id, image_path, db)
except ValueError as e:
if 'File size exceeds' in str(e):
raise HTTPException(413, str(e))
raise Prevention
- Enforce a client-side size check and warn before upload.
- Configure the reverse proxy (nginx client_max_body_size) consistently with MAX_FILE_SIZE.
- Guide users to downscale camera photos before upload.
When it happens
Trigger: Uploading an avatar larger than 5 MB; high-resolution phone photos (often 5-15 MB JPEGs) used directly without pre-compression; animated/lossless PNG exports from design tools.
Common situations: Mobile uploads of full-camera-resolution photos; users exporting PNGs from Photoshop/Figma; GIF/BMP converted to large PNGs; HEIC converted to JPEG at very high quality.
Related errors
- Invalid format '{img_format}'. Allowed formats: PNG, JPEG, W
- Invalid image file: {str(e)}
- Profile not found: {profile_id}
- No samples found for profile {profile_id}
- HTTP error! status: ${response.status}
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/5fd196f431119c3a.
Report an issue: GitHub.