iOS: 48MP photos fail to upload (413) — JPEG conversion without downscaling
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- ios, typescript
- Domain
- api, mobile-dev
Research direction
Start in sources/hooks/useImagePicker.ts at normalizePickedAssetForUpload and inspect how the converted asset is passed into the upload flow. Add bounded dimensions to the JPEG conversion, then reproduce the 48MP iOS upload and confirm the converted file stays under 10MB and no longer receives a 413 response.
Written by the indexing model from the issue text.
Description
Summary
On iOS, picked photos are converted to JPEG (q0.92) without any downscaling. 48MP photos from recent iPhones (6048×8064) end up over the 10MB server limit after conversion, and the upload is rejected with 413. 12MP photos and screenshots work fine.
Steps to reproduce
- iPhone 17 Pro Max, camera in 48MP mode
- Pick a 48MP HEIC photo (~6.3MB original) in a chat
- Send → fails with a generic "attachment too large" toast; server returns 413
Root cause
In sources/hooks/useImagePicker.ts, normalizePickedAssetForUpload runs:
await ImageManipulator.manipulateAsync(asset.uri, [], {
compress: 0.92,
format: ImageManipulator.SaveFormat.JPEG,
});
No maxWidth/maxHeight is passed, so the resolution is unchanged. HEIC→JPEG at 6048×8064 with q0.92 produces a file larger than the 10MB limit.
The client-side size guard checks the original asset.fileSize (6.3MB — passes), but the converted blob is what gets encrypted and uploaded. The server (attachmentRoutes.ts) enforces 10MB on the actual upload, so the request fails with 413 and the user only sees a generic error toast.
Evidence
| Asset | Original | After conversion | Result |
|---|---|---|---|
| 48MP photo (HEIC) | 6.3MB | >10MB | ❌ 413 |
| 12MP photo (HEIC) | ~1.8MB | 2.69MB | ✅ |
| Screenshot (PNG) | 6.38MB | 0.62MB | ✅ |
The converted size is what dominates, not the original.
Suggested fix
Add downsampling in normalizePickedAssetForUpload:
await ImageManipulator.manipulateAsync(asset.uri, [], {
compress: 0.92,
format: ImageManipulator.SaveFormat.JPEG,
maxWidth: 3072,
maxHeight: 3072,
});
A 48MP photo then converts to ~2–4MB, well within the limit, and model input size shrinks for all photos.
Alternative considered — skipping conversion entirely when the original is already ≤10MB — does not work end-to-end: HEIC is not an accepted input format for the model API, and the CLI (verified on 1.2.2) performs no HEIC transcoding before handing attachments to the model. So the JPEG conversion itself is still needed; only the missing downscale is the bug.
Environment
- happy iOS app (Expo production build, published 2026-08-26)
- iPhone 17 Pro Max, iOS 26
- Dominant language
- TypeScript
- Stars
- 23.8k
- Forks
- 2k
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 13
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from slopus/happy
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100