RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-customfield-json

error-invalid-customfield-json

Error message

Invalid JSON for Custom Fields

What it means

saveCustomFieldsWithoutValidation throws error-invalid-customfield-json when JSON.parse of the Accounts_CustomFields setting string fails inside getCustomFieldsMeta. The admin-managed setting that declares custom profile fields is not valid JSON, so every profile save that includes custom fields dies before touching the database.

Source

Thrown at apps/meteor/server/lib/users/saveCustomFieldsWithoutValidation.ts:16

import type { IUser } from '@rocket.chat/core-typings';
import type { Updater } from '@rocket.chat/models';
import { Subscriptions, Users } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
import type { ClientSession } from 'mongodb';

import { trim } from '../../../lib/utils/stringUtils';
import { onceTransactionCommitedSuccessfully } from '../../database/utils';
import { settings } from '../../settings';
import { notifyOnSubscriptionChangedByUserIdAndRoomType } from '../notifyListener';

const getCustomFieldsMeta = function (customFieldsMeta: string) {
	try {
		return JSON.parse(customFieldsMeta);
	} catch (e) {
		throw new Meteor.Error('error-invalid-customfield-json', 'Invalid JSON for Custom Fields');
	}
};
export const saveCustomFieldsWithoutValidation = async function (
	userId: string,
	formData: Record<string, any>,
	options?: {
		_updater?: Updater<IUser>;
		session?: ClientSession;
	},
): Promise<void> {
	const customFieldsSetting = settings.get<string>('Accounts_CustomFields');
	if (!customFieldsSetting || trim(customFieldsSetting).length === 0) {
		return;
	}

	// configured custom fields in setting
	const customFieldsMeta = getCustomFieldsMeta(customFieldsSetting);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Open Administration > Settings > Accounts > Custom Fields and fix the JSON (validate it with JSON.parse or a JSON linter first); an empty value is also acceptable
  2. When writing the setting programmatically, always build it with JSON.stringify instead of string concatenation
  3. Add a pre-save validation of the setting so a bad value can never be persisted

Example fix

// before
Settings.update('Accounts_CustomFields', rawConfigText); // may persist broken JSON

// after
JSON.parse(rawConfigText); // throws before saving if invalid
Settings.update('Accounts_CustomFields', rawConfigText);
Defensive patterns

Strategy: validation

Validate before calling

// validate the admin setting before it can poison every profile save
const parseCustomFields = (raw: string): Record<string, unknown> | null => {
  try {
    return JSON.parse(raw);
  } catch {
    return null; // reject the value before persisting it
  }
};

Type guard

const isValidCustomFieldsSetting = (raw: string): boolean => {
  const t = raw.trim();
  return t.length === 0 || parseCustomFields(t) !== null;
};

Try / catch

try {
  await saveCustomFieldsWithoutValidation(uid, formData);
} catch (e) {
  if (isMeteorErrorCode(e, 'error-invalid-customfield-json')) {
    // workspace-level misconfiguration: fix Accounts_CustomFields, not this request
    notifyAdmins('Accounts_CustomFields contains invalid JSON');
  }
}

Prevention

When it happens

Trigger: Any saveCustomFields call (profile save with custom fields, user creation with custom fields) after an admin saved a malformed Accounts_CustomFields value: trailing commas, single quotes, unquoted keys, comments, or smart quotes pasted from a word processor.

Common situations: Hand-editing the custom-fields definition in the admin UI; copy-pasting examples from docs/blogs that contain comments or YAML-style syntax; an integration writing the setting programmatically without JSON.stringify.

Understand the failure class

Related errors


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