{"record":{"id":"2a1f6c8d3bf8e64b","repo":"hcengineering/platform","slug":"failed-to-add-contact","errorCode":null,"errorMessage":"Failed to add contact","messagePattern":"Failed to add contact","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"services/telegram/pod-telegram/src/telegram.ts","lineNumber":310,"sourceCode":"    }\n\n    return true\n  }\n\n  async addContact (contact: { phone: string, firstName: string, lastName: string }): Promise<void> {\n    const result = await this.client.invoke(\n      new Api.contacts.ImportContacts({\n        contacts: [\n          new Api.InputPhoneContact({\n            ...contact,\n            clientId: bigInt(0)\n          })\n        ]\n      })\n    )\n\n    if (result.imported.length < 1) {\n      throw Error('Failed to add contact')\n    }\n  }\n\n  getToken (): string | undefined {\n    // TODO: Need recheck\n    // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n    return (this.client.session.save() as never as string) ?? undefined\n  }\n}\n\nexport type TelegramConnectionInterface = InstanceType<typeof TelegramConnection>\n\n// Notice: not really elegant solution, for now have no better idea\n// how to reorganize this mess. This helper works like buffer for connections\n// that are not yet signed in and unified telegram connection creator.\nexport const telegram = new (class TelegramHelper {\n  readonly conns = new Map<string, TelegramConnection>()\n  readonly ttls = new Map<string, NodeJS.Timeout>()","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/telegram/pod-telegram/src/telegram.ts#L292-L328","documentation":"addContact() imports the contact into the user's Telegram account via contacts.importContacts; if the imported contacts list is empty, Telegram did not match any account and the contact cannot be added, so it throws.","triggerScenarios":"sendMsg triggers addContact with a phone number that does not correspond to any Telegram user, or a malformed/incorrect phone value that Telegram cannot resolve.","commonSituations":"Messaging a phone number that never joined Telegram; storing phone numbers in the wrong format (missing country code); messaging bots or deleted accounts.","solutions":["Verify the target phone number is a registered Telegram account and includes the country code","Normalize the phone number format (E.164) before addContact","Check whether the target is a bot/handle and use the appropriate messaging path instead","Catch the error and inform the user the contact could not be reached"],"exampleFix":"// before\nawait sendMessage(target) // throws 'Failed to add contact' for non-Telegram numbers\n// after\nconst e164 = normalizeToE164(target)\nif (!isRegisteredTelegramUser(e164)) {\n  notify(`No Telegram account for ${e164}`)\n  return\n}\nawait sendMessage(e164)","handlingStrategy":"try-catch","validationCode":"const e164 = normalizeToE164(phone)\nif (!/^\\+\\d{7,15}$/.test(e164)) {\n  throw new Error(`Invalid phone format: ${phone}`)\n}","typeGuard":"function isValidPhone(v: unknown): v is string {\n  return typeof v === 'string' && /^\\+\\d{7,15}$/.test(v)\n}","tryCatchPattern":"try {\n  await sendMessage(target)\n} catch (err) {\n  if (err.message === 'Failed to add contact') {\n    notify(`Cannot reach ${target}: no Telegram account found`)\n  }\n}","preventionTips":["Normalize all phone numbers to E.164 before contact import","Check the target has a Telegram account before messaging","Handle bot/handle targets through a different path than phone contacts"],"tags":["telegram","contacts","messaging"],"backgroundTag":"contact-not-found","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}