# Fix: Auth Not Configured on Railway

> **Status:** Investigation complete, solution identified, awaiting Railway dashboard configuration

**Date:** 2026-01-30
**Priority:** P0 - Critical (blocks all login functionality)
**Affected:** Railway deployment only (local works fine)

---

## Summary

**Problem:** Login page shows "Auth not configured - VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY missing on Railway"

**Root Cause:** Railway environment variables missing the frontend build-time variables `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY`. Vite embeds these into JavaScript bundles during build, not at runtime.

**Solution:** Add missing environment variables to Railway dashboard and redeploy.

---

## Root Cause Analysis

### Investigation Process (Systematic Debugging)

#### Phase 1: Evidence Gathering
1. ✅ Confirmed error message in browser console: "Auth not configured"
2. ✅ Traced to `admin/src/lib/supabase.js:27` - mock client fallback
3. ✅ Found bundle contains warning but no credentials
4. ✅ Verified `import.meta.env` was replaced during build (zero occurrences in bundle)

#### Phase 2: Pattern Analysis
1. ✅ Compared Railway deployment vs local development
2. ✅ Found LESSONS.md already documents this pattern (lines 47-52)
3. ✅ Railway config only has `SUPABASE_URL` (backend), not `VITE_SUPABASE_URL` (frontend)
4. ✅ Build happens on Railway via Nixpacks running `npm run build`

#### Phase 3: Hypothesis
**Theory:** Railway Nixpacks runs build without frontend env vars available

**Evidence:**
- `railway.json` specifies `startCommand` but not build vars
- Nixpacks auto-detects and runs `npm run build`
- Build runs but without `VITE_*` env vars in Railway environment
- Result: bundles contain `undefined` for Supabase credentials

**Test:** Add `VITE_*` vars to Railway, trigger rebuild, verify credentials embedded

#### Phase 4: Solution
Add to Railway environment variables and redeploy to trigger rebuild.

---

## Data Flow Analysis

### How It Should Work

```
1. Railway Environment
   ├─ SUPABASE_URL (backend runtime)
   ├─ SUPABASE_ANON_KEY (backend runtime)
   ├─ VITE_SUPABASE_URL (frontend build) ← MISSING
   └─ VITE_SUPABASE_ANON_KEY (frontend build) ← MISSING

2. Nixpacks Build Process
   └─ npm run build
      └─ cd admin && npm install && npm run build
         └─ vite build
            ├─ Reads import.meta.env.VITE_SUPABASE_URL
            ├─ Embeds value into JavaScript bundle
            └─ Outputs to admin/dist/

3. Deploy Process
   └─ cp -r dist/* ../public/
      └─ npm start (node src/index.js)
         └─ Serves public/ as static files

4. Browser Loads
   └─ /assets/index-*.js (with embedded credentials)
      └─ createClient(VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY)
```

### Current Broken Flow

```
1. Railway Environment (BEFORE FIX)
   ├─ SUPABASE_URL ✓
   ├─ SUPABASE_ANON_KEY ✓
   ├─ VITE_SUPABASE_URL ✗ MISSING
   └─ VITE_SUPABASE_ANON_KEY ✗ MISSING

2. Vite Build
   └─ import.meta.env.VITE_SUPABASE_URL = undefined
   └─ import.meta.env.VITE_SUPABASE_ANON_KEY = undefined

3. Bundle Contains
   const supabaseUrl = undefined;
   const supabaseAnonKey = undefined;

4. Runtime Checks
   if (supabaseUrl && supabaseAnonKey) {  // FALSE
   } else {
     console.warn('Supabase credentials not configured...')
     // Mock client created
   }
```

---

## The Fix

### Step 1: Add Environment Variables to Railway

Via **Railway Dashboard:**
1. Go to https://railway.app/dashboard
2. Select `rateright-growth` project
3. Variables tab
4. Add:
   ```
   VITE_SUPABASE_URL         = <same as SUPABASE_URL>
   VITE_SUPABASE_ANON_KEY    = <same as SUPABASE_ANON_KEY>
   VITE_API_URL              = https://rateright-growth-production.up.railway.app
   ```

Via **Railway CLI:**
```bash
railway variables set VITE_SUPABASE_URL="https://your-project.supabase.co"
railway variables set VITE_SUPABASE_ANON_KEY="your-anon-key"
railway variables set VITE_API_URL="https://rateright-growth-production.up.railway.app"
```

### Step 2: Redeploy
Railway will automatically redeploy when variables are added via dashboard.

Or manually trigger:
```bash
railway up --detach
```

### Step 3: Verify

**Check build logs:**
```
✓ npm run build
✓ vite build
✓ Build completed successfully
✓ Copying files to ../public/
```

**Check browser console:**
```
Should see: [Supabase] Client initialized with URL: https://...
Should NOT see: Supabase credentials not configured
```

**Test login:**
1. Visit login page
2. Enter phone number
3. OTP should send successfully
4. No auth errors

---

## Why This Wasn't Caught Earlier

1. **Local development works fine** - developers have `.env` files with credentials
2. **Previous "fix" was manual workaround** - commit `60d88e0` rebuilt frontend locally with creds and committed bundles
3. **Railway docs focus on backend env vars** - frontend build-time vars are less obvious
4. **Vite's behavior is non-obvious** - env vars embedded at build, not runtime

---

## Prevention

### ✅ Added to Documentation
- Created `docs/RAILWAY-ENV-SETUP.md` - comprehensive Railway env var guide
- Updated `docs/LESSONS.md` - added Railway-specific notes
- Documented in this file for future reference

### ✅ Checklist for Future Railway Deployments
```
Backend env vars (runtime):
□ SUPABASE_URL
□ SUPABASE_ANON_KEY
□ SUPABASE_SERVICE_ROLE_KEY
□ All Twilio vars
□ All API keys

Frontend env vars (build-time):
□ VITE_SUPABASE_URL
□ VITE_SUPABASE_ANON_KEY
□ VITE_API_URL
```

### ✅ Verification Test
Add to CI/CD or manual checklist:
```bash
# After Railway deploy, verify bundle has credentials:
curl https://your-app.railway.app/assets/index-*.js | grep -o "Auth not configured"
# Should return: (empty) - means credentials are embedded
```

---

## Technical Insights

### Vite Environment Variable Behavior

**Build-time variables (VITE_*):**
- Read from environment during `vite build`
- Replaced in source code via string replacement
- Embedded into final JavaScript bundle
- Cannot be changed without rebuilding
- Not available via `process.env` in browser

**Example:**
```javascript
// Source code
const url = import.meta.env.VITE_SUPABASE_URL;

// After vite build
const url = "https://project.supabase.co";
```

### Railway + Nixpacks Build Process

**What Nixpacks does:**
1. Detects Node.js project (`package.json`)
2. Reads `scripts.build` → finds `npm run build`
3. Installs dependencies
4. Runs build script with Railway env vars available
5. Runs start script

**Critical:** Build happens on Railway servers with Railway env vars, not locally with `.env` files.

### Why Two Sets of Vars?

| Variable | Used By | When | Where |
|----------|---------|------|-------|
| `SUPABASE_URL` | Backend Node.js | Runtime | Server-side code |
| `VITE_SUPABASE_URL` | Frontend Vite | Build time | Browser bundle |
| `SUPABASE_ANON_KEY` | Backend | Runtime | Server-side |
| `VITE_SUPABASE_ANON_KEY` | Frontend | Build time | Browser bundle |

They have the same values but serve different purposes in the deployment pipeline.

---

## Next Steps

1. ✅ Investigation complete
2. ✅ Documentation created
3. ⏳ **Add env vars to Railway dashboard** (requires Railway access)
4. ⏳ **Verify deployment** (check logs and test login)
5. ⏳ **Update Work Tracker** (mark task complete)

---

## References

- Investigation transcript: (this session)
- Code location: `admin/src/lib/supabase.js:3-4`
- Error location: `admin/src/lib/supabase.js:27`
- Build script: `package.json:9`
- Vite config: `admin/vite.config.js`
- Railway config: `railway.json`

---

**Investigator:** CC-VPS (Claude Code)
**Method:** Systematic debugging (superpowers:systematic-debugging)
**Time:** ~20 minutes (investigation + documentation)
**Confidence:** High - root cause identified with evidence
