`buzz upload file` rejects PDFs/documents the relay accepts — agents can't attach files the desktop can
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
Thank you so much for releasing this beast in the wild! 🤗
**Describe the bug**
The CLI applies a client-side MIME **allowlist** that is stricter than the relay it uploads to, on the endpoint that exists to accept generic files. Files are rejected locally and never reach the server.
`crates/buzz-cli/src/client.rs:1116` (`upload_file`):
```rust
if !ALLOWED_MIMES.contains(&mime.as_str()) {
return Err(CliError::Usage(format!("unsupported file type: {mime}")));
}
```
`ALLOWED_MIMES` (`client.rs:63`) is `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `video/mp4`.
But the same function uploads to `PUT {relay}/upload` (`client.rs:1144`) — the generic route, which the relay validates with `validate_file_content()` (`crates/buzz-media/src/validation.rs:159`) using a **denylist** (`BLOCKED_FILE_MIME_TYPES`: HTML/JS/SVG + executables). `application/pdf` is not blocked, and `file_mime_to_ext()` explicitly maps `application/pdf → pdf` and `…spreadsheetml.sheet → xlsx`.
So the server accepts these; the client refuses to send them.
**To Reproduce**
1. `buzz upload file --file report.xlsx`
2. → `{"error":"user_error","message":"unsupported file type: application/zip"}`
(an `.xlsx` is a zip container, so `infer` reports `application/zip` — a type the relay
accepts on this endpoint.)
3. Same for `.pdf`, `.docx`, `.csv`.
4. `buzz messages send --file report.xlsx` fails identically — same code path, and this is the
path agents use to attach anything.
Confirmed the server side by patching the check out locally and re-running: the same file
uploads and returns a normal `{url, sha256, size}` descriptor. Nothing server-side had to
change.
**Expected behavior**
The CLI should accept what the relay accepts. Either mirror `BLOCKED_FILE_MIME_TYPES`, or drop the pre-check and surface the server's 4xx — the server is the authority anyway, since it verifies magic bytes rather than a client-supplied type.
**Why this matters**
This is the file-attachment path for **agents**. Desktop already handles generic attachments (#2381 describes the composer as accepting "images, videos, PDFs, archives, and other supported files"), so an agent cannot attach a file that a human can attach to the same channel on the same relay.
Concretely: an agent that generates a spreadsheet or PDF report has no way to deliver it through Buzz.
**Additional context**
Two smaller issues in the same function:
- **Size cap**: non-video files are checked against `MAX_IMAGE_BYTES` (50 MB, `client.rs:1121`). The relay has a separate `max_file_bytes` for the generic path, which the CLI has no notion of.
- **Error message**: `unsupported file type: application/pdf` states the opposite of the truth for this relay, which makes the mismatch hard to diagnose.
If the relay ever exposes Blossom **BUD-06** (`HEAD /upload`), asking the server for its
requirements would remove the duplicated policy entirely — the client would stop carrying a
second copy of a policy that only the server can enforce.
**Environment**
- CLI built from source at `9cc9652c`; code references above are against `main` @ `a64cc71f`, where `client.rs` is unchanged since that build
- Relay: self-hosted, `main` @ `ab3af828`
- macOS 15 (arm64)
Contributor guide
Assessment
This issue has not been assessed yet.