{"record":{"id":"fe3a96e0e10c0a0f","repo":"RocketChat/Rocket.Chat","slug":"invalid-setting","errorCode":null,"errorMessage":"invalid-setting","messagePattern":"invalid-setting","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/appearance.ts","lineNumber":62,"sourceCode":"\t\t\t\t'Livechat_offline_email',\n\t\t\t\t'Livechat_conversation_finished_message',\n\t\t\t\t'Livechat_conversation_finished_text',\n\t\t\t\t'Livechat_registration_form',\n\t\t\t\t'Livechat_name_field_registration_form',\n\t\t\t\t'Livechat_email_field_registration_form',\n\t\t\t\t'Livechat_registration_form_message',\n\t\t\t\t'Livechat_hide_watermark',\n\t\t\t\t'Livechat_background',\n\t\t\t\t'Livechat_widget_position',\n\t\t\t\t'Livechat_hide_system_messages',\n\t\t\t\t'Omnichannel_allow_visitors_to_close_conversation',\n\t\t\t\t'Livechat_hide_expand_chat',\n\t\t\t];\n\n\t\t\tconst valid = settings.every((setting) => validSettingList.includes(setting._id));\n\n\t\t\tif (!valid) {\n\t\t\t\tthrow new Error('invalid-setting');\n\t\t\t}\n\n\t\t\tconst dbSettings = await Settings.findByIds(validSettingList, { projection: { _id: 1, value: 1, type: 1, values: 1 } })\n\t\t\t\t.map((dbSetting) => {\n\t\t\t\t\tconst setting = settings.find(({ _id }) => _id === dbSetting._id);\n\t\t\t\t\tif (!setting || dbSetting.value === setting.value) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (dbSetting.type === 'multiSelect' && (!Array.isArray(setting.value) || !validateValues(setting.value, dbSetting.values))) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (dbSetting?.type) {\n\t\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t_id: dbSetting._id,\n\t\t\t\t\t\t\t\tvalue: setting.value === 'true' || setting.value === true,","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/omnichannel/appearance.ts#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Check every id for exact case-sensitive spelling (e.g. 'Livechat_hide_watermark', not 'Livechat_Hide_Watermark').","If a legit appearance setting is rejected, your client and server are on different versions — align them or branch the payload per server version.","Remove non-appearance settings from this call; general settings go through the settings API, not livechat/appearance."],"exampleFix":"// before\nawait post('/api/v1/livechat/appearance', [\n  { _id: 'Livechat_title', value: 'Support' },\n  { _id: 'Site_Url', value: 'https://x' }, // not whitelisted -> invalid-setting\n]);\n\n// after\nconst ALLOWED = new Set(['Livechat_title', 'Livechat_title_color' /* ...rest of whitelist */]);\nawait post(\n  '/api/v1/livechat/appearance',\n  payload.filter((s) => ALLOWED.has(s._id)),\n);","handlingStrategy":"validation","validationCode":"const ALLOWED_APPEARANCE = new Set([\n  'Livechat_title', 'Livechat_title_color', 'Livechat_enable_message_character_limit',\n  'Livechat_message_character_limit', 'Livechat_show_agent_info', 'Livechat_show_agent_email',\n  'Livechat_display_offline_form', 'Livechat_offline_form_unavailable', 'Livechat_offline_message',\n  'Livechat_offline_success_message', 'Livechat_offline_title', 'Livechat_offline_title_color',\n  'Livechat_offline_email', 'Livechat_conversation_finished_message', 'Livechat_conversation_finished_text',\n  'Livechat_registration_form', 'Livechat_name_field_registration_form', 'Livechat_email_field_registration_form',\n  'Livechat_registration_form_message', 'Livechat_hide_watermark', 'Livechat_background',\n  'Livechat_widget_position', 'Livechat_hide_system_messages',\n  'Omnichannel_allow_visitors_to_close_conversation', 'Livechat_hide_expand_chat',\n]);\nconst safe = payload.filter((s) => ALLOWED_APPEARANCE.has(s._id));\nif (safe.length !== payload.length) console.warn('dropped non-whitelisted settings');\nawait post('/api/v1/livechat/appearance', safe);","typeGuard":"function isAppearanceSetting(s: unknown): s is { _id: string; value: unknown } {\n  return typeof s === 'object' && s !== null && typeof (s as any)._id === 'string' && ALLOWED_APPEARANCE.has((s as any)._id);\n}","tryCatchPattern":null,"preventionTips":["Derive the payload from GET livechat/appearance so ids match the server's whitelist.","Re-generate the id list per server version instead of hardcoding forever.","Keep case-sensitive setting ids; lint against typos."],"tags":["omnichannel","appearance","settings","whitelist","rest-api"],"backgroundTag":"schema-validation-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}