- Shipped
- September 7, 2026 at 3:41 AM UTC
- Author
- Kamo
- Commit
- 71b3030
Sending a text failed with "The message could not be sent. Try again in a moment.". Telnyx's own answer, from the voipservice log, was specific: Telnyx POST /messages failed: The source phone number was deemed invalid by the carrier. The stored sender was `9492989960`. Telnyx requires E.164, so it rejected the send outright. Root cause is a field named `e164` that nothing ever normalised. Its javadoc promises "the number in full, as it should be displayed and dialled", but OrgPhoneNumberService wrote whatever arrived -- from a carrier's from_phone_number, or from discovery -- straight into it, trimmed only. That value then flows to **************** and out as `from`. Every layer downstream trusted the field's name. Normalise at both write paths (save and upsertDiscovered) and where the carrier instance itself is created or edited, using the existing E164.normalize helper. It refuses rather than guesses, so a number it cannot place keeps its raw text instead of being silently mangled into a plausible wrong number. Two paths also disagreed about a member's from-number: /capability read only MEMBER_VOIP_CONFIG, which is written for the primary holder alone, while the send path reads the assignment table. A member holding a shared line they are not primary on was told they had no number to text from, while a send for them would have succeeded. Both now use one resolver, and assigning a number writes the legacy column for that member too. Live rows were repaired directly; no non-E.164 sender remains in org_phone_number, bulk_text_provider_instance or member_voip_config.