RocketChat/Rocket.Chat · error · Meteor.Error
error-no-file-uploaded
error-no-file-uploaded
Error message
No file was uploaded
What it means
Thrown by POST rooms.upload/:rid (multipart) when MultipartUploadHandler.parseRequest returns no 'file' part. The handler expects a multipart form with a 'file' field capped by FileUpload_MaxFileSize. Reaching this branch means the request either had no file field, failed file-size handling, or was not multipart at all.
Source
Thrown at apps/meteor/server/api/v1/rooms.ts:281
},
);
API.v1.addRoute(
'rooms.media/:rid',
{ authRequired: true },
{
async post() {
if (!(await canAccessRoomIdAsync(this.urlParams.rid, this.userId))) {
return API.v1.forbidden();
}
const { file, fields } = await MultipartUploadHandler.parseRequest(this.incoming, {
field: 'file',
maxSize: settings.get<number>('FileUpload_MaxFileSize'),
});
if (!file) {
throw new Meteor.Error('error-no-file-uploaded', 'No file was uploaded');
}
const expiresAt = new Date();
expiresAt.setHours(expiresAt.getHours() + 24);
let content;
if (fields.content) {
try {
content = JSON.parse(fields.content);
} catch (e) {
console.error(e);
throw new Meteor.Error('invalid-field-content');
}
}
const details = {
name: file.filename,View on GitHub (pinned to f9d3ec372b)
Solutions
- Send the request as multipart/form-data with a part literally named 'file'.
- In axios/fetch/Postman, use FormData and append('file', blob, name) — do not JSON.stringify the body.
- Confirm FileUpload_MaxFileSize in admin settings is greater than your file size and > 0.
- If using the resumable/Streamer flow for large files, use rooms.mediaConfirm instead of rooms.upload.
Example fix
// before (wrong: JSON body)
await rest.post(`/api/v1/rooms.upload/${rid}`, { file: base64 });
// after (multipart with field 'file')
const form = new FormData();
form.append('file', fileBlob, fileBlob.name);
await rest.post(`/api/v1/rooms.upload/${rid}`, form); Defensive patterns
Strategy: validation
Validate before calling
function buildUploadForm(file: Blob, fields?: Record<string, string>): FormData {
if (!(file instanceof Blob)) throw new TypeError('file must be a Blob/File');
const form = new FormData();
form.append('file', file, (file as File).name || 'upload.bin');
for (const [k, v] of Object.entries(fields ?? {})) form.append(k, v);
return form;
} Type guard
function isMultipartReady(form: FormData): boolean {
return form.has('file');
} Try / catch
try {
await rest.post(`/api/v1/rooms.upload/${rid}`, form, { headers: form.getHeaders?.() });
} catch (e) {
if (isMeteorError(e, 'error-no-file-uploaded')) {
// verify field name is 'file' and Content-Type is multipart/form-data
} else throw e;
} Prevention
- Always use FormData and append('file', ...).
- Let the HTTP library set Content-Type with the boundary — don't set it manually.
- Confirm FileUpload_MaxFileSize > file.size before sending.
When it happens
Trigger: POST /api/v1/rooms.upload/:rid with a JSON body instead of multipart/form-data; multipart request whose file field is named something other than 'file'; empty form; file rejected upstream of the handler so 'file' is undefined.
Common situations: Client forgetting to set Content-Type: multipart/form-data; using 'attachment' or 'upload' as the field name; file uploads disabled or FileUpload_MaxFileSize set to 0; proxy/gateway stripping the multipart boundary.
Related errors
- invalid-file
- Room not found
- error-room-param-not-provided
- error-room-not-found
- error-roomid-param-not-provided
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/fdab5547f3926004.
Report an issue: GitHub.