RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-setting-value

error-invalid-setting-value

Error message

Invalid setting value ${value}

What it means

For settings of type 'int', 'timespan' or 'range', saveSettingsBulk first checks the payload value is a Number (meteor check) and then that Number.isInteger(value) holds. Any non-integer - a float like 50.5, a numeric string like '50', null or undefined - fails with 'error-invalid-setting-value' and the message 'Invalid setting value <value>'. This is a payload type error, not a bounds problem.

Source

Thrown at apps/meteor/server/settings/lib/saveSettingsBulk.ts:27

import { getSettingPermissionId } from '../../../app/authorization/lib';
import { hasPermissionAsync } from '../../lib/authorization/hasPermission';
import { notifyOnSettingChangedById } from '../../lib/notifyListener';
import { validateSettingRules } from '../../lib/settingValidationRules';
import { disableCustomScripts } from '../../lib/shared/disableCustomScripts';
import { checkSettingValueBounds } from '../checkSettingValueBonds';

const validJSON = Match.Where((value: string) => {
	try {
		value === '' || JSON.parse(value);
		return true;
	} catch (_) {
		throw new Meteor.Error('Invalid JSON provided');
	}
});

const checkInteger = (value: ISetting['value']) => {
	if (!Number.isInteger(value)) {
		throw new Meteor.Error('error-invalid-setting-value', `Invalid setting value ${value}`, {
			method: 'saveSettings',
		});
	}
};

export type SaveSettingsAudit = {
	username: string;
	ip: string;
	useragent: string;
};

export const saveSettingsBulk = async (
	uid: string,
	params: { _id: ISetting['_id']; value: ISetting['value']; editor?: ISettingColor['editor'] }[],
	audit: SaveSettingsAudit,
): Promise<void> => {
	const settingsNotAllowed: ISetting['_id'][] = [];

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Send integer JSON numbers, never strings: value 30 not value '30'
  2. Round or Math.trunc float inputs before submitting (50.5 -> 50 or 51 as appropriate)
  3. Validate the payload client-side with Number.isInteger before calling saveSettings
  4. Check the error message - it prints the offending value, making string-typed numbers obvious

Example fix

// before
await fetch('/api/v1/settings', { body: JSON.stringify([{ _id: 'API_User_Limit', value: "25" }]) });
// -> error-invalid-setting-value: Invalid setting value 25

// after
await fetch('/api/v1/settings', { body: JSON.stringify([{ _id: 'API_User_Limit', value: 25 }]) });
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof value !== 'number' || !Number.isInteger(value)) {
	value = Math.round(Number(value)); // coerce string or float input to an integer number
}
Meteor.call('saveSettings', [{ _id: settingId, value }]);

Type guard

const isIntegerSettingValue = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v);

Try / catch

catch (err) {
	if (err instanceof Meteor.Error && err.error === 'error-invalid-setting-value' && /Invalid setting value/.test(err.reason)) {
		// value was a string or float: fix the payload type and retry
	} else throw err;
}

Prevention

When it happens

Trigger: REST/API callers sending numbers as strings ('25' instead of 25); UI code passing a parsed float (from an input element or formula) without rounding; scripts reusing values from configs where the number was serialized as a string.

Common situations: Integrations written against loosely typed JSON; client form inputs returning strings; values round-tripped through systems that stringify numbers (URL query params, CSV exports).

Related errors


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