You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the composer, the only per-attachment actions are editing the description and removing the attachment. New files are always appended at the end, and once the attachment limit is reached (e.g. 4/4), adding files is blocked entirely with "You can only attach up to 4 files."
This makes replacing a single attachment painful. Real scenario I just hit: I attached 4 images and wrote alt text for each, then the server rejected the first image with a 422 (file size). To swap in a fixed version of that image in the same position, I had to remove all attachments and re-add them in order — losing all 4 alt texts I'd written.
The failing-upload case makes this worse: the rejected attachment just sits there with an error; there's no way to retry or point it at a fixed file.
Solution I'd like
Either one of these would solve the issue on its own (both would be even better):
Replace action on an attachment — pick a new file for an existing slot, keeping its description and position. This would also be the natural retry path for failed uploads.
Drag'n'drop reordering — then I could remove just the bad attachment, add the fixed file (it lands at the end), and drag it back into place, with the other attachments' alt texts untouched.
Alternatives considered
Current workaround: remove all attachments and re-add them in the right order, re-typing every alt text. Works, but loses a lot of writing.
Avoiding oversized files up front: doesn't fully help, because the server can reject files that are under the advertised limit, and no client-side check can predict that. My rejected file was a 13.0 MB PNG on mastodon.social (advertised image_size_limit is 16 MB) — Phanpy correctly showed no warning, yet the server returned 422 Validation failed: File must be less than 16 MB. The official web UI rejects the same file, so it's a server-side issue (possibly related to <16MB indexed color images detected as too big mastodon/mastodon#32983). Such rejections of valid-looking files will keep happening, so the composer needs a graceful recovery path.
Other
Where this lives in the code:
Attachment items only get onDescriptionChange and onRemove: src/components/compose.jsx (MediaAttachment usage, ~line 1596).
New files are appended: setMediaAttachments((prev) => [...prev, ...mediaFiles]).
Hard block at max attachments: processFiles in src/components/compose.jsx (~line 290).
Problem I have
In the composer, the only per-attachment actions are editing the description and removing the attachment. New files are always appended at the end, and once the attachment limit is reached (e.g. 4/4), adding files is blocked entirely with "You can only attach up to 4 files."
This makes replacing a single attachment painful. Real scenario I just hit: I attached 4 images and wrote alt text for each, then the server rejected the first image with a 422 (file size). To swap in a fixed version of that image in the same position, I had to remove all attachments and re-add them in order — losing all 4 alt texts I'd written.
The failing-upload case makes this worse: the rejected attachment just sits there with an error; there's no way to retry or point it at a fixed file.
Solution I'd like
Either one of these would solve the issue on its own (both would be even better):
Alternatives considered
image_size_limitis 16 MB) — Phanpy correctly showed no warning, yet the server returned422 Validation failed: File must be less than 16 MB. The official web UI rejects the same file, so it's a server-side issue (possibly related to <16MB indexed color images detected as too big mastodon/mastodon#32983). Such rejections of valid-looking files will keep happening, so the composer needs a graceful recovery path.Other
Where this lives in the code:
onDescriptionChangeandonRemove:src/components/compose.jsx(MediaAttachment usage, ~line 1596).setMediaAttachments((prev) => [...prev, ...mediaFiles]).processFilesinsrc/components/compose.jsx(~line 290).