RocketChat/Rocket.Chat · error · Error

invalid-setting

Error message

invalid-setting

What it means

POST /api/v1/livechat/appearance accepts a body that is an array of { _id, value } settings, but only for a fixed whitelist (Livechat_title, Livechat_title_color, Livechat_enable_message_character_limit, ... Omnichannel_allow_visitors_to_close_conversation, Livechat_hide_expand_chat — see validSettingList in appearance.ts). If any submitted _id is not on the whitelist, settings.every(...) fails and 'invalid-setting' is thrown.

Solutions

  1. GET livechat/appearance first and submit only the _ids that endpoint acknowledges; or filter your payload against the whitelist constant in apps/meteor/server/api/v1/omnichannel/appearance.ts.
  2. Check every id for exact case-sensitive spelling (e.g. 'Livechat_hide_watermark', not 'Livechat_Hide_Watermark').
  3. If a legit appearance setting is rejected, your client and server are on different versions — align them or branch the payload per server version.
  4. Remove non-appearance settings from this call; general settings go through the settings API, not livechat/appearance.

Example fix

// before
await post('/api/v1/livechat/appearance', [
  { _id: 'Livechat_title', value: 'Support' },
  { _id: 'Site_Url', value: 'https://x' }, // not whitelisted -> invalid-setting
]);

// after
const ALLOWED = new Set(['Livechat_title', 'Livechat_title_color' /* ...rest of whitelist */]);
await post(
  '/api/v1/livechat/appearance',
  payload.filter((s) => ALLOWED.has(s._id)),
);
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_APPEARANCE = new Set([
  'Livechat_title', 'Livechat_title_color', 'Livechat_enable_message_character_limit',
  'Livechat_message_character_limit', 'Livechat_show_agent_info', 'Livechat_show_agent_email',
  'Livechat_display_offline_form', 'Livechat_offline_form_unavailable', 'Livechat_offline_message',
  'Livechat_offline_success_message', 'Livechat_offline_title', 'Livechat_offline_title_color',
  'Livechat_offline_email', 'Livechat_conversation_finished_message', 'Livechat_conversation_finished_text',
  'Livechat_registration_form', 'Livechat_name_field_registration_form', 'Livechat_email_field_registration_form',
  'Livechat_registration_form_message', 'Livechat_hide_watermark', 'Livechat_background',
  'Livechat_widget_position', 'Livechat_hide_system_messages',
  'Omnichannel_allow_visitors_to_close_conversation', 'Livechat_hide_expand_chat',
]);
const safe = payload.filter((s) => ALLOWED_APPEARANCE.has(s._id));
if (safe.length !== payload.length) console.warn('dropped non-whitelisted settings');
await post('/api/v1/livechat/appearance', safe);

Type guard

function isAppearanceSetting(s: unknown): s is { _id: string; value: unknown } {
  return typeof s === 'object' && s !== null && typeof (s as any)._id === 'string' && ALLOWED_APPEARANCE.has((s as any)._id);
}

Prevention

When it happens

Trigger: Sending any setting id outside the whitelist (e.g. a generic setting like 'Site_Url', a typo like 'Livechat_titles', or a renamed setting) in the POST body; sending a settings object/map keyed by id instead of the array-of-{_id,value} shape after passing schema validation with extra items.

Common situations: Version drift: a client built against a different Rocket.Chat release submits ids this server's whitelist never had or has since removed; copy-paste of setting ids from the general settings UI; assuming the endpoint writes arbitrary settings.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/api/v1/omnichannel/appearance.ts:62

				'Livechat_offline_email',
				'Livechat_conversation_finished_message',
				'Livechat_conversation_finished_text',
				'Livechat_registration_form',
				'Livechat_name_field_registration_form',
				'Livechat_email_field_registration_form',
				'Livechat_registration_form_message',
				'Livechat_hide_watermark',
				'Livechat_background',
				'Livechat_widget_position',
				'Livechat_hide_system_messages',
				'Omnichannel_allow_visitors_to_close_conversation',
				'Livechat_hide_expand_chat',
			];

			const valid = settings.every((setting) => validSettingList.includes(setting._id));

			if (!valid) {
				throw new Error('invalid-setting');
			}

			const dbSettings = await Settings.findByIds(validSettingList, { projection: { _id: 1, value: 1, type: 1, values: 1 } })
				.map((dbSetting) => {
					const setting = settings.find(({ _id }) => _id === dbSetting._id);
					if (!setting || dbSetting.value === setting.value) {
						return;
					}

					if (dbSetting.type === 'multiSelect' && (!Array.isArray(setting.value) || !validateValues(setting.value, dbSetting.values))) {
						return;
					}

					switch (dbSetting?.type) {
						case 'boolean':
							return {
								_id: dbSetting._id,
								value: setting.value === 'true' || setting.value === true,

View on GitHub (pinned to b2c16d5842)