LibreChat/api/server/routes/files
Danny Avila 5e464bc930
📎 fix: Alias Shell Script MIME Variants to application/x-sh (#14817)
* 📎 fix: Alias Shell Script MIME Variants to `application/x-sh`

Chrome on Linux reports `.sh` files as `application/x-shellscript`
(freedesktop shared-mime-info) and libmagic reports `text/x-shellscript`.
Neither string appears anywhere in the source, so uploads were rejected
even though `application/x-sh` is in the default allowlist and
`codeTypeMapping` maps `sh` to it — `inferMimeType` only consults the
extension map when the client sends no type at all, so a non-empty
browser value passed straight through to the allowlist check.

Alias both variants to the canonical `application/x-sh`, matching the
existing treatment of `text/x-markdown` and `application/x-zip-compressed`.

Also attach `statusCode`/`body` to multer file-filter rejections. Without
them the error misses the `isCustomError` branch in `ErrorController` and
falls through to a bare `500 An unknown error occurred.`, so the rejection
reason was logged server-side but never reached the client. The upload
hook already surfaces `error.response.data.message`, so a rejected file
now explains itself instead of showing a generic upload failure.

* 🔁 refactor: Move Upload Error Contract Into `packages/api`

Addresses codex P1 on #14817.

The producer of the `statusCode`/`body` pair now sits beside its consumer:
`isCustomError` and `ErrorController` are already in
`packages/api/src/middleware/error.ts`, and `CustomError` is already in
`packages/api/src/types/error.ts` — only the construction of that pair was
stranded in legacy JS. `createCustomError` is exported from the same module
as the guard that recognizes it, and `multer.js` is back to a thin caller.

Also pins the `.sh` back-compat claim with tests: configs from the
documented workarounds (`application/x-sh` per #4660/#5689/#6297, and the
broad patterns from #14804) still accept a `.sh` upload after the alias
rewrites the type. A negative control confirms the endpoint config is
genuinely in play rather than falling back to the default allowlist.
2026-08-14 01:12:23 -04:00
..
speech 🧵 fix: Preserve Upload Context Across Multipart Routes (#13072) 2026-05-11 15:46:48 -04:00
avatar.js
files.agents.test.js 🧷 fix: Align Agent File Attachment Ownership (#14149) 2026-07-07 16:23:48 -04:00
files.js 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It (#14470) 2026-07-28 07:37:26 -04:00
files.test.js 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It (#14470) 2026-07-28 07:37:26 -04:00
images.agents.test.js
images.js 🛟 fix: Keep File Uploads Alive With SSE Heartbeats (#14295) 2026-07-21 19:27:09 -04:00
index.js 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It (#14470) 2026-07-28 07:37:26 -04:00
index.limiters.test.js 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It (#14470) 2026-07-28 07:37:26 -04:00
index.tenant.test.js 🔒 fix: Bound /files/usage TTL Hold Instead of Clearing It (#14470) 2026-07-28 07:37:26 -04:00
multer.js 📎 fix: Alias Shell Script MIME Variants to application/x-sh (#14817) 2026-08-14 01:12:23 -04:00
multer.spec.js 📎 fix: Alias Shell Script MIME Variants to application/x-sh (#14817) 2026-08-14 01:12:23 -04:00
preview.spec.js 🧷 fix: Align Agent File Attachment Ownership (#14149) 2026-07-07 16:23:48 -04:00