block / block/buzz

`buzz upload file` rejects PDFs/documents the relay accepts — agents can't attach files the desktop can

Open
#2,963 3 comments 1 reaction 0 assignees View on GitHub
bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.