Describe the bug
Buzz Mobile cannot attach an Apple Voice Memo (.m4a). A real iOS upload
failed with HTTP 422:
moov atom not at front of file (not fast-start)
After that failed attempt, retrying surfaced a follow-on error because the
temporary file-provider path no longer existed:
PathNotFoundException: Cannot retrieve length of file, path = '.../Neue Aufnahme 3.m4a'
This is broader than a missing fast-start rewrite. Current main
(a96af89526f7181543e7651100a944aa8e21812b) routes every ISO-BMFF container
into the video pipeline:
fn should_stream_as_video(sniff: &[u8]) -> bool {
infer::get(sniff).is_some_and(|kind| kind.mime_type() == "video/mp4")
|| buzz_media::looks_like_iso_bmff(sniff)
}
An M4A Voice Memo is ISO-BMFF, so it reaches validate_video_file(). A normal
non-fast-start Voice Memo fails at check_moov_before_mdat() with the observed
422. Merely moving moov would not fully solve the case because the same video
validator later requires a video track.
The generic file path is not a fallback: validate_file_content() explicitly
rejects ISO-BMFF and every detected audio/* until an audio sanitizer exists.
The CLI similarly rejects a synthetic M4A before upload as
unsupported file type: audio/m4a.
Relevant code:
crates/buzz-relay/src/api/media.rs (should_stream_as_video, upload_blob)
crates/buzz-media/src/validation.rs (validate_file_content,
validate_video_file, check_moov_before_mdat)
mobile/lib/shared/relay/media_upload.dart (uploadFile sends generic files
as application/octet-stream)
Steps to reproduce
- Record a memo in Apple Voice Memos on iPhone.
- Attach/share the resulting
.m4a into a Buzz Mobile composer as a file.
- Send the message.
- Observe HTTP 422 with
moov atom not at front of file (not fast-start).
- Retry after the failed attempt.
- Observe that the temporary share/file-provider URL may already be gone,
producing PathNotFoundException.
A minimal local fixture showing the common layout can be generated with:
ffmpeg -f lavfi -i anullsrc=r=44100:cl=mono -t 1 \
-c:a aac -b:a 64k -movflags -faststart voice-memo-repro.m4a
Its top-level order is ftyp | mdat | moov. Buzz CLI currently rejects it as
unsupported file type: audio/m4a; the Mobile generic-file route reaches the
relay because it labels the body application/octet-stream.
Expected behavior
Preferred: Buzz accepts a normal AAC/M4A voice memo through an explicit audio
pipeline that remuxes/sanitizes the container, strips metadata, emits a stable
audio/mp4/audio/m4a descriptor, and does not require a video track.
Minimum safe behavior until audio uploads are supported:
- Detect M4A before enqueue/upload and show a clear "audio attachments are not
supported yet" message instead of a misleading video fast-start error.
- Copy file-provider/share-extension inputs into app-owned temporary storage
before queueing so a failed upload can be retried without
PathNotFoundException.
Suggested regression coverage
- Non-fast-start audio-only M4A (
ftyp | mdat | moov) does not enter the video
validator.
- Fast-start audio-only M4A (
ftyp | moov | mdat) does not fail for missing
video track when audio support is enabled.
- A queued iOS file-provider attachment remains readable for retry after the
provider revokes its temporary URL.
Version and platform
- Buzz version: unknown (reported 2026-08-13; bug is present in current source
at a96af895)
- OS: iOS / iPhone
Logs / additional context
No matching open or closed issue was found for m4a, voice memo,
audio upload, moov atom, or fast-start before filing.
Describe the bug
Buzz Mobile cannot attach an Apple Voice Memo (
.m4a). A real iOS uploadfailed with HTTP 422:
After that failed attempt, retrying surfaced a follow-on error because the
temporary file-provider path no longer existed:
This is broader than a missing fast-start rewrite. Current
main(
a96af89526f7181543e7651100a944aa8e21812b) routes every ISO-BMFF containerinto the video pipeline:
An M4A Voice Memo is ISO-BMFF, so it reaches
validate_video_file(). A normalnon-fast-start Voice Memo fails at
check_moov_before_mdat()with the observed422. Merely moving
moovwould not fully solve the case because the same videovalidator later requires a video track.
The generic file path is not a fallback:
validate_file_content()explicitlyrejects ISO-BMFF and every detected
audio/*until an audio sanitizer exists.The CLI similarly rejects a synthetic M4A before upload as
unsupported file type: audio/m4a.Relevant code:
crates/buzz-relay/src/api/media.rs(should_stream_as_video,upload_blob)crates/buzz-media/src/validation.rs(validate_file_content,validate_video_file,check_moov_before_mdat)mobile/lib/shared/relay/media_upload.dart(uploadFilesends generic filesas
application/octet-stream)Steps to reproduce
.m4ainto a Buzz Mobile composer as a file.moov atom not at front of file (not fast-start).producing
PathNotFoundException.A minimal local fixture showing the common layout can be generated with:
Its top-level order is
ftyp | mdat | moov. Buzz CLI currently rejects it asunsupported file type: audio/m4a; the Mobile generic-file route reaches therelay because it labels the body
application/octet-stream.Expected behavior
Preferred: Buzz accepts a normal AAC/M4A voice memo through an explicit audio
pipeline that remuxes/sanitizes the container, strips metadata, emits a stable
audio/mp4/audio/m4adescriptor, and does not require a video track.Minimum safe behavior until audio uploads are supported:
supported yet" message instead of a misleading video fast-start error.
before queueing so a failed upload can be retried without
PathNotFoundException.Suggested regression coverage
ftyp | mdat | moov) does not enter the videovalidator.
ftyp | moov | mdat) does not fail for missingvideo track when audio support is enabled.
provider revokes its temporary URL.
Version and platform
at
a96af895)Logs / additional context
No matching open or closed issue was found for
m4a,voice memo,audio upload,moov atom, orfast-startbefore filing.