RocketChat/Rocket.Chat · error · Error
error-contact-not-found
error-contact-not-found
Error message
error-contact-not-found
What it means
resolveContactConflicts (POST /api/v1/omnichannel/contact.resolveConflicts) loads the contact with LivechatContacts.findOneEnabledById; if no enabled contact matches contactId, this plain Error with the code as its message is thrown. 'Not found' here covers both a wrong _id and a contact that exists but is disabled/deleted.
Source
Thrown at apps/meteor/server/lib/omnichannel/contacts/resolveContactConflicts.ts:27
contactId: string;
name?: string;
customFields?: Record<string, unknown>;
contactManager?: string;
wipeConflicts?: boolean;
};
export async function resolveContactConflicts(params: ResolveContactConflictsParams): Promise<ILivechatContact> {
const { contactId, name, customFields, contactManager, wipeConflicts } = params;
const contact = await LivechatContacts.findOneEnabledById<Pick<ILivechatContact, '_id' | 'customFields' | 'conflictingFields'>>(
contactId,
{
projection: { _id: 1, customFields: 1, conflictingFields: 1 },
},
);
if (!contact) {
throw new Error('error-contact-not-found');
}
if (!contact.conflictingFields?.length) {
throw new Error('error-contact-has-no-conflicts');
}
if (contactManager) {
await validateContactManager(contactManager);
}
let updatedConflictingFieldsArr: ILivechatContactConflictingField[] = [];
if (wipeConflicts) {
const value = await Settings.incrementValueById('Resolved_Conflicts_Count', contact.conflictingFields.length, {
returnDocument: 'after',
});
if (value) {
void notifyOnSettingChanged(value);
}View on GitHub (pinned to b2c16d5842)
Solutions
- Fetch the contact first (GET /api/v1/omnichannel/contact) and confirm it returns and is enabled
- Re-list contacts and copy the current _id; ids are 17-char Mongo ObjectIDs and easy to truncate
- If the contact was disabled intentionally, resolve conflicts on the active merged/primary contact instead
Defensive patterns
Strategy: validation
Validate before calling
const contact = await LivechatContacts.findOneEnabledById(contactId, { projection: { _id: 1 } });
if (!contact) {
throw new Error(`No enabled contact with id ${contactId}`);
}
await resolveContactConflicts(params); Type guard
const isValidContactId = (id: unknown): id is string =>
typeof id === 'string' && /^[0-9a-f]{17}$/i.test(id); Try / catch
try {
await resolveContactConflicts(params);
} catch (err) {
if (err instanceof Error && err.message === 'error-contact-not-found') {
// re-fetch contact list; id is wrong, stale, or contact is disabled
}
throw err;
} Prevention
- Always copy contactId from a live API response, never from stale exports
- Remember findOneEnabledById excludes disabled contacts — a 200 on GET does not guarantee enabled
- Log contactIds at submit time to debug copy/truncation issues fast
When it happens
Trigger: Calling contact.resolveConflicts with a contactId that is mistyped, belongs to a deleted contact, or to a contact whose 'enabled' flag is false (findOneEnabledById filters disabled contacts).
Common situations: Contact was deleted or disabled by another process between listing and resolving; client copied the id from an outdated export; id truncated when hand-copied.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- error-contact-not-found
- error-contact-not-found
- error-visitor-not-found
- error-contact-not-found
- error-contact-manager-not-found
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/01f70bf7efd96160.
Report an issue: GitHub.