# Inbox SMS Error Investigation & Fix Plan

**Created:** Jan 21, 2026
**Priority:** Blocking (Monday callers need SMS)
**Severity:** 60%
**Reported:** Excellence Report flagged "inbox: API error sending messages"

---

## Problem Statement

Users are experiencing "API error" when sending SMS from the Messages/Inbox page. This is blocking sales calls on Monday.

---

## Investigation Summary

### Data Flow Traced

```
Frontend (Messages.jsx)
    ↓ smsApi.send({ leadId, message })
API Client (client.js)
    ↓ POST /api/sms/send
Backend (sms.js:228-450)
    ↓ Load lead → sendSMS()
Twilio Service (twilio.js)
    ↓ client.messages.create()
Twilio API
```

### Root Cause Identified

**Phone normalization is NOT applied when sending by leadId.**

In `src/routes/sms.js:269-283`:
```javascript
let toPhone = phone ? normalizeAustralianPhone(phone) : null;

if (leadId && supabase) {
  // ...fetch lead...
  lead = data;
  toPhone = lead.phone; // ⚠️ Uses phone directly, NO normalization!
}
```

When a lead's phone is stored in local format (e.g., `0412345678`) instead of E.164 (`+61412345678`), Twilio rejects it with an error like "The 'To' number is not a valid phone number."

### Contributing Factors

1. **No phone validation before Twilio call** - Invalid formats reach Twilio and fail
2. **Error message is unclear** - Shows raw Twilio error, not user-friendly
3. **Lead phone storage inconsistent** - Some leads have local format, some have E.164

### Files Involved

| File | Line | Issue |
|------|------|-------|
| `src/routes/sms.js` | 283 | Phone not normalized when using leadId |
| `src/routes/sms.js` | 348-351 | Raw Twilio error passed to frontend |
| `src/services/twilio.js` | 83-108 | No phone format validation before API call |

---

## Solution

### Fix 1: Normalize phone before sending (Critical)

**File:** `src/routes/sms.js:283`

**Current:**
```javascript
toPhone = lead.phone;
```

**Fixed:**
```javascript
toPhone = normalizeAustralianPhone(lead.phone) || lead.phone;
```

This ensures all phones are normalized to E.164 format before hitting Twilio.

### Fix 2: Validate phone format before Twilio call (Safety)

**File:** `src/routes/sms.js` after line 287

**Add:**
```javascript
// Validate phone format before sending
if (!toPhone || !toPhone.startsWith('+61')) {
  return res.status(400).json({
    error: `Invalid phone format: ${toPhone}. Expected Australian mobile (+61...)`
  });
}
```

### Fix 3: Better error message (UX)

**File:** `src/routes/sms.js:350-351`

**Current:**
```javascript
if (!result.success) {
  return res.status(500).json({ error: result.error });
}
```

**Fixed:**
```javascript
if (!result.success) {
  console.error(`SMS send failed to ${toPhone}:`, result.error);
  const userMessage = result.error.includes('not a valid phone')
    ? 'Invalid phone number format. Please check the lead\'s phone number.'
    : result.error.includes('blacklist')
    ? 'This number has been blocked from receiving SMS.'
    : `Failed to send SMS: ${result.error}`;
  return res.status(500).json({ error: userMessage });
}
```

---

## Implementation Steps

- [x] **Step 1:** Apply phone normalization fix in `sms.js:283` ✅
- [x] **Step 2:** Add phone format validation after line 287 ✅
- [x] **Step 3:** Improve error messages at line 350-351 ✅
- [ ] **Step 4:** Test locally with various phone formats (QA)
- [ ] **Step 5:** Build and deploy (QA)
- [ ] **Step 6:** Test in production (QA)

---

## Success Criteria

1. SMS sends successfully when lead phone is in any format (local, E.164, etc.)
2. Clear error message if phone format is truly invalid
3. No more "API error" reports from Messages page

---

## Notes for Builder

- Import `normalizeAustralianPhone` is already at top of sms.js
- Phone util handles: `+61...`, `61...`, `04...`, and `4...` formats
- Test with phones like: `0412345678`, `+61412345678`, `412345678`

---

## Notes for QA

- Test sending SMS to lead with phone `0412345678` (should work after fix)
- Test sending to lead with phone `+61412345678` (should still work)
- Test with invalid phone like `123` (should show clear error)
- Check Railway logs for any new error patterns

---

## Risk Assessment

| Risk | Mitigation |
|------|------------|
| Normalization fails | Fallback to original phone with || operator |
| Edge case formats | Phone util handles common AU formats |
| Breaking existing flows | Fix is additive, doesn't change working paths |

---

**Estimated effort:** 30 mins (quick fix)
**Ready for Builder:** Yes
