hcengineering/platform · error · Error
Phone number is already used
Error message
Phone number is already used
What it means
addUser registers a telegram user for a workspace and stores the record keyed by (phone, workspace). If a record with the same phone already exists for that workspace, it throws 'Phone number is already used' to prevent duplicate bindings of one phone within a workspace.
Source
Thrown at services/telegram/pod-telegram/src/platform.ts:29
private readonly storageAdapter: StorageAdapter,
private readonly clientMap: Map<string, WorkspaceWorker>,
private readonly storage: Collection<UserRecord>
) {}
async close (): Promise<void> {
await Promise.all(
[...this.clientMap.values()].map(async (worker) => {
await worker.close()
})
)
}
async addUser (tgUser: TgUser): Promise<void> {
const { workspace, phone } = tgUser as any // TODO: FIXME
const res = await this.storage.findOne({ phone, workspace })
if (res !== null) {
throw Error('Phone number is already used')
}
let wsWorker = this.clientMap.get(workspace)
if (wsWorker === undefined) {
const [userStorage, lastMsgStorage, channelStorage] = await PlatformWorker.createStorages()
wsWorker = await WorkspaceWorker.create(
this.ctx,
this.storageAdapter,
workspace,
userStorage,
lastMsgStorage,
channelStorage
)
this.clientMap.set(workspace, wsWorker)
}
await wsWorker.addUser(tgUser)View on GitHub (pinned to 63e28dc964)
Solutions
- Check for an existing registration (storage.findOne({phone, workspace})) and reuse it instead of throwing.
- Remove the existing user (removeUser) before re-adding, or implement an upsert.
- Ask the user for a different phone number if the old binding is intentional.
- For stale records from crashed signups, clean up the storage record manually then retry.
Example fix
// before
const res = await this.storage.findOne({ phone, workspace })
if (res !== null) {
throw Error('Phone number is already used')
}
// after
const res = await this.storage.findOne({ phone, workspace })
if (res !== null) {
if (res.user === tgUser.user) return // idempotent re-add for same user
throw Error('Phone number is already used')
} Defensive patterns
Strategy: try-catch
Validate before calling
const existing = await storage.findOne({ phone, workspace })
if (existing !== null) console.warn('Phone already registered for workspace; re-add will fail') Try / catch
try {
await platform.addUser(tgUser)
} catch (err) {
if (err.message === 'Phone number is already used') {
console.warn('Phone already bound to workspace; skipping or updating existing user')
return
}
throw err
} Prevention
- Check for an existing (phone, workspace) record before calling addUser.
- Make signup idempotent for the same user instead of throwing.
- Clean up partial registrations from crashed signups.
- Prevent two accounts sharing one phone at the UI level.
When it happens
Trigger: Calling addUser with a TgUser whose phone was previously registered in the same workspace — e.g. re-linking an account, retrying a signup that partially persisted, or two accounts sharing one phone number.
Common situations: Users re-installing the bot and signing up again, testing with the same phone across accounts, or a previous registration that crashed after the storage write but before completion.
Related errors
- Duplicated storage name ${config.name}, skipping config:${st
- User is not signed in
- Cannot create message, group not found: cardId = ${event.car
- Missing response body
- Network error ${error}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/065891f74d024e54.
Report an issue: GitHub.