# Troubleshooting JWT 401 Errors ## Problem Getting "HTTP 401: Invalid JWT" errors on all screens in the Flutter app. ## Root Causes (in order of likelihood) ### 1. Migrations Not Applied to Production Database ⭐ MOST LIKELY **Symptom:** JWT is valid, but RLS policies reference functions that don't exist yet. **Check:** 1. Go to Supabase Dashboard: https://app.supabase.com/project/zwkihedetedlatyvplyz/sql/new 2. Run this diagnostic script: ```sql -- Check if critical functions exist SELECT 'has_block_between' as function_name, CASE WHEN EXISTS ( SELECT 1 FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname = 'public' AND p.proname = 'has_block_between' ) THEN '✓ EXISTS' ELSE '✗ MISSING - THIS IS THE PROBLEM' END as status; SELECT 'is_mutual_follow' as function_name, CASE WHEN EXISTS ( SELECT 1 FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname = 'public' AND p.proname = 'is_mutual_follow' ) THEN '✓ EXISTS' ELSE '✗ MISSING - THIS IS THE PROBLEM' END as status; ``` **Fix if MISSING:** ```bash # Apply all migrations in order cd c:\Webs\Sojorn # Open Supabase SQL Editor and run each migration file in order: # 1. supabase/migrations/20260106000001_core_identity_and_boundaries.sql # 2. supabase/migrations/20260106000002_content_and_engagement.sql # 3. supabase/migrations/20260106000003_moderation_and_trust.sql # 4. supabase/migrations/20260106000004_row_level_security.sql # 5. supabase/migrations/20260106000005_trending_system.sql # 6. supabase/migrations/add_is_official_column.sql # 7. supabase/migrations/fix_has_block_between_null_handling.sql ``` --- ### 2. Environment Variables Not Passed to Flutter **Symptom:** App can't connect to Supabase at all, or uses wrong credentials. **Check:** ```powershell # Make sure you're running with the PowerShell script: cd c:\Webs\Sojorn\sojorn_app .\run_dev.ps1 ``` **Not this:** ```powershell flutter run # ❌ WRONG - no environment variables ``` **Verify in console output:** - You should NOT see: "Missing Supabase config" error on startup - You SHOULD see the app launch successfully --- ### 3. Wrong Supabase Credentials **Symptom:** JWT signature validation fails. **Check:** Verify credentials in `.env` match your Supabase dashboard: - Dashboard: https://app.supabase.com/project/zwkihedetedlatyvplyz/settings/api - Local: `c:\Webs\Sojorn\.env` Compare: - `SUPABASE_URL` should be: `https://zwkihedetedlatyvplyz.supabase.co` - `SUPABASE_ANON_KEY` should start with: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` **Fix:** If they don't match, update `.env` and the PowerShell scripts: - `run_dev.ps1` - `run_chrome.ps1` - `.vscode/launch.json` --- ### 4. Session Expired or Invalid **Symptom:** JWT was valid but has expired. **Check:** ```dart // Add this to your sign-in flow temporarily print('Session expiry: ${session.expiresAt}'); print('Current time: ${DateTime.now().millisecondsSinceEpoch ~/ 1000}'); ``` **Fix:** - Sign out and sign in again - Check if Supabase Auth is configured correctly in dashboard --- ## Quick Fix (Applied) I've updated `api_service.dart` to gracefully handle JWT/RLS errors in these methods: - `hasProfile()` - now returns `false` on error instead of throwing - `hasCategorySelection()` - now returns `false` on error instead of throwing - `_getEnabledCategoryIds()` - now returns empty set on error **What this does:** - Prevents app crashes when RLS policies fail - Allows signup flow to proceed even with JWT issues - Prints errors to console so we can see what's actually failing **Console output to look for:** ``` hasProfile error (treating as false): [error details] hasCategorySelection error (treating as false): [error details] _getEnabledCategoryIds error: [error details] ``` --- ## Next Steps 1. **Hot restart the Flutter app** (not just hot reload - full restart) - Press `Ctrl+C` in terminal - Run `.\run_dev.ps1` again 2. **Check the Flutter console** for the error messages we added 3. **Try signing in** and see if you get past the error 4. **Share the console output** with the error details so we can pinpoint the exact issue 5. **Run the diagnostic SQL** in Supabase to check if functions exist --- ## Most Likely Solution Based on the symptoms (JWT error on all screens), the issue is almost certainly: **The RLS policies reference `has_block_between()` function, but the migration that creates this function hasn't been applied to the production database yet.** **Quick fix:** 1. Go to Supabase SQL Editor 2. Copy entire contents of `supabase/migrations/20260106000001_core_identity_and_boundaries.sql` 3. Paste and run 4. Restart Flutter app This will create the missing `has_block_between()` and `is_mutual_follow()` functions that RLS policies depend on.