Skip to content

Account deletion leaves verified Twilio caller IDs orphaned #7640

Description

@mdmohsin7

Summary

When a user deletes their omi account, our backend wipes their Firestore data (including the users/{uid}/phone_numbers subcollection) but does not delete the corresponding verified caller IDs from Twilio. Those caller IDs remain registered to our Twilio account forever.

Impact

Twilio rejects any future attempt to verify a phone number that already has a caller ID on the account, regardless of which omi user previously owned it. So if user A verifies a phone number, deletes their account, and later user B (or A re-signing up with a new uid) tries to verify the same number, the /v1/phone/numbers/verify endpoint fails with error 21450 → "This phone number is already registered."

We hit this in production today — the only fix is an engineer manually calling Twilio's outgoing_caller_ids({sid}).delete() after confirming no live omi user owns the number.

Root cause

  • backend/routers/users.py:151 (delete_account) → spawns background delete_user_data in backend/database/users.py:646.
  • delete_user_data walks user subcollections and deletes Firestore docs, but never touches Twilio.
  • Compare with backend/routers/phone_calls.py:182 (remove_phone_number), which correctly calls delete_caller_id(twilio_sid) before deleting the Firestore record. The same teardown is missing on the account-deletion path.

Proposed fix

In the account-deletion background wipe, before the Firestore subcollection deletion runs, iterate users/{uid}/phone_numbers and call utils.twilio_service.delete_caller_id(twilio_sid) for each entry that has a twilio_sid set. Best-effort: log and continue on individual Twilio failures so a transient Twilio error can't block account deletion.

Acceptance criteria

  • Deleting an account that has verified phone number(s) removes the corresponding caller IDs from Twilio.
  • Twilio failures (network, 5xx, already-deleted) are logged but do not prevent the Firestore wipe from completing.
  • Unit test covers: (a) cleanup called once per phone_numbers doc with a twilio_sid, (b) docs without a twilio_sid are skipped, (c) a Twilio exception on one doc does not stop the others or the downstream wipe.

Out of scope

  • Retroactive cleanup of caller IDs from already-deleted accounts (one-time ops task, not code).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions