RocketChat/Rocket.Chat · error · Error

message-length-exceeds-character-limit

Error message

message-length-exceeds-character-limit

What it means

POST /api/v1/livechat/message enforces the server setting pair Livechat_enable_message_character_limit / Livechat_message_character_limit: when the limit is enabled and msg.length exceeds parseInt(limit), the message is rejected with 'message-length-exceeds-character-limit'. The widget config exposes this as `limitTextLength` (falling back to Message_MaxAllowedSize) so clients can pre-validate.

Solutions

  1. Enforce the limit client-side using limitTextLength from the livechat configuration the widget already receives, and disable the send button beyond it.
  2. Split long content into multiple messages, each under the limit.
  3. If the business requires longer messages, an admin can raise or disable Livechat_message_character_limit (Omnichannel settings).

Example fix

// before
await post('/api/v1/livechat/message', { token, rid, msg }); // long paste -> rejected

// after
const { limitTextLength } = livechatConfig; // from livechat settings/config
if (limitTextLength && msg.length > limitTextLength) {
  msg = `${msg.slice(0, limitTextLength - 1)}\u2026`; // or split into chunks
}
await post('/api/v1/livechat/message', { token, rid, msg });
Defensive patterns

Strategy: validation

Validate before calling

// Enforce the server-configured limit client-side before sending
const { limitTextLength } = livechatConfig; // from the livechat settings/config payload
function fitsLimit(msg: string): boolean {
  return !limitTextLength || msg.length <= limitTextLength;
}
function chunk(msg: string): string[] {
  if (fitsLimit(msg)) return [msg];
  const size = limitTextLength as number;
  return msg.match(new RegExp(`.{1,${size}}`, 'g')) ?? [];
}
for (const part of chunk(msg)) await post('/api/v1/livechat/message', { token, rid, msg: part });

Type guard

function isWithinLimit(msg: string, limit?: number): msg is string {
  return !limit || msg.length <= limit;
}

Try / catch

try { await postMessage(token, rid, msg); } catch (e) { if (e.message === 'message-length-exceeds-character-limit') { for (const part of chunk(msg, limitTextLength)) await postMessage(token, rid, part); } else throw e; }

Prevention

When it happens

Trigger: Visitor pastes a long text with the character limit enabled; admin lowers the limit after widgets already loaded; a custom integration sends oversized payloads without checking the configured limit.

Common situations: Pasted logs/stack traces in chat; per-workpace compliance limits set to a small value; integrations assuming the default Message_MaxAllowedSize instead of the livechat-specific limit.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/api/v1/omnichannel/message.ts:49

			const guest = await findGuest(token);
			if (!guest) {
				throw new Error('invalid-token');
			}

			const room = await findRoom(token, rid);
			if (!room) {
				throw new Error('invalid-room');
			}

			if (!room.open) {
				throw new Error('room-closed');
			}

			if (
				settings.get('Livechat_enable_message_character_limit') &&
				msg.length > parseInt(settings.get('Livechat_message_character_limit'))
			) {
				throw new Error('message-length-exceeds-character-limit');
			}

			const _id = this.bodyParams._id || Random.id();

			const messageToSend = {
				guest,
				message: {
					_id,
					rid,
					msg,
					token,
				},
				agent,
				roomInfo: {
					source: {
						type: isWidget(this.request.headers) ? OmnichannelSourceType.WIDGET : OmnichannelSourceType.API,
					},
				},

View on GitHub (pinned to b2c16d5842)