RocketChat/Rocket.Chat · error · Meteor.Error

invalid-field-content

invalid-field-content

Error message

invalid-field-content

What it means

Thrown by POST /api/v1/rooms.media/:rid when the optional multipart field content is present but JSON.parse(fields.content) throws, meaning the field is not valid JSON. The code has no human-readable message, only the error code 'invalid-field-content'. The parsed value becomes the attachment message's content sent on to mediaConfirm.

Solutions

  1. Stringify before appending: form.append('content', JSON.stringify(obj))
  2. Validate before upload: JSON.parse(content) must not throw on the client
  3. Omit the content field entirely when no structured payload is needed

Example fix

// before
form.append('content', { msg: 'see attachment', rid }); // '[object Object]' -> invalid-field-content

// after
form.append('content', JSON.stringify({ msg: 'see attachment', rid }));
Defensive patterns

Strategy: validation

Validate before calling

let contentStr: string | undefined;
if (content != null) {
  contentStr = typeof content === 'string' ? content : JSON.stringify(content);
  JSON.parse(contentStr); // throws locally before the server does
}

Try / catch

try {
  form.append('content', contentStr);
  await fetch(url, { method: 'POST', body: form });
} catch (e: any) {
  if (e?.response?.data?.errorType === 'invalid-field-content') {
    form.set('content', JSON.stringify(safePayload)); // resend with serialized JSON
  }
  throw e;
}

Prevention

When it happens

Trigger: POST rooms.media with content appended as a raw object (FormData serializes it to '[object Object]'); single-quoted or trailing-comma JSON; content truncated by a proxy; concatenated JSON fragments.

Common situations: Clients appending structured payloads without JSON.stringify; template strings producing invalid JSON; content built from user input with unescaped quotes; partial uploads where the content part was cut off.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-08-18). Data as JSON: /api/errors/5ab89968a31f5593. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/server/api/v1/rooms.ts:298

				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,
				size: file.size,
				type: file.mimetype,
				rid: this.urlParams.rid,
				userId: this.userId,
				content,
				expiresAt,
			};

			// TODO: In the future, we should isolate file receival from storage and post-processing.
			const fileStore = FileUpload.getStore('Uploads');
			const uploadedFile = await fileStore.insert(details, file.tempFilePath);

			uploadedFile.path = FileUpload.getPath(`${uploadedFile._id}/${encodeURI(uploadedFile.name || '')}`);

View on GitHub (pinned to e4b8178b20)