RocketChat/Rocket.Chat · error · Error

invalid-custom-field

invalid-custom-field

Error message

invalid-custom-field

What it means

In setCustomFields (POST /api/v1/omnichannel/custom-field / livechat custom-field route), LivechatCustomField.findOneById(key) returned null: the field definition you are writing to does not exist. Rocket.Chat only stores values for fields that are defined in the custom-field registry, so an undefined key is rejected before any visitor/room data is touched.

Source

Thrown at apps/meteor/server/lib/omnichannel/custom-fields.ts:66

	await LivechatContacts.updateById(contact._id, { $set: contactCustomFieldsToUpdate });
}

export async function setCustomFields({
	token,
	key,
	value,
	overwrite,
}: {
	key: string;
	value: string;
	overwrite: boolean;
	token: string;
}): Promise<number> {
	livechatLogger.debug({ msg: 'Setting custom fields data for visitor with token', token });

	const customField = await LivechatCustomField.findOneById(key);
	if (!customField) {
		throw new Error('invalid-custom-field');
	}

	if (customField.regexp !== undefined && customField.regexp !== '') {
		const regexp = new RegExp(customField.regexp);
		if (!regexp.test(value)) {
			throw new Error(i18n.t('error-invalid-custom-field-value', { field: key }));
		}
	}

	let result;
	if (customField.scope === 'room') {
		result = await LivechatRooms.updateDataByToken(token, key, value, overwrite);
	} else {
		result = await LivechatVisitors.updateLivechatDataByToken(token, key, value, overwrite);

		const visitor = await LivechatVisitors.getVisitorByToken(token, { projection: { _id: 1 } });
		if (visitor) {
			const contacts = await LivechatContacts.findAllByVisitorId(visitor._id).toArray();

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Create the field first: Administration > Omnichannel > Custom Fields, or POST /api/v1/livechat/custom-fields
  2. Use the exact field _id (case-sensitive) — verify against GET /api/v1/livechat/custom-fields
  3. If the field was deleted intentionally, stop sending it from the widget/integration

Example fix

// before
await POST('/api/v1/livechat/custom-field', { token, key: 'Company', value: 'ACME', overwrite: true }); // field id is 'company'

// after
await POST('/api/v1/livechat/custom-field', { token, key: 'company', value: 'ACME', overwrite: true });
Defensive patterns

Strategy: validation

Validate before calling

const definition = await LivechatCustomField.findOneById(key);
if (!definition) throw new Error(`Custom field '${key}' is not defined; create it first`);
await setCustomFields({ token, key, value, overwrite });

Type guard

const isDefinedCustomFieldKey = (key: string, defined: Set<string>): boolean => defined.has(key);

Try / catch

try {
  await setCustomFields({ token, key, value, overwrite });
} catch (err) {
  if (err instanceof Error && err.message === 'invalid-custom-field') {
    // key is not a defined field id: create the field or fix the key, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: POST /livechat/custom-field with a key that is not the exact _id of a defined custom field — typo, wrong case, using the field's label instead of its id, or the field was deleted.

Common situations: Field created in one environment (staging) but not in the target; field deleted during cleanup while widgets still submit it; client sends human label ('Company') instead of the id ('company').

Related errors


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