4.8 KiB
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:
- Go to Supabase Dashboard: https://app.supabase.com/project/zwkihedetedlatyvplyz/sql/new
- Run this diagnostic script:
-- 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:
# 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:
# Make sure you're running with the PowerShell script:
cd c:\Webs\Sojorn\sojorn_app
.\run_dev.ps1
Not this:
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_URLshould be:https://zwkihedetedlatyvplyz.supabase.coSUPABASE_ANON_KEYshould start with:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Fix:
If they don't match, update .env and the PowerShell scripts:
run_dev.ps1run_chrome.ps1.vscode/launch.json
4. Session Expired or Invalid
Symptom: JWT was valid but has expired.
Check:
// 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 returnsfalseon error instead of throwinghasCategorySelection()- now returnsfalseon 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
-
Hot restart the Flutter app (not just hot reload - full restart)
- Press
Ctrl+Cin terminal - Run
.\run_dev.ps1again
- Press
-
Check the Flutter console for the error messages we added
-
Try signing in and see if you get past the error
-
Share the console output with the error details so we can pinpoint the exact issue
-
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:
- Go to Supabase SQL Editor
- Copy entire contents of
supabase/migrations/20260106000001_core_identity_and_boundaries.sql - Paste and run
- Restart Flutter app
This will create the missing has_block_between() and is_mutual_follow() functions that RLS policies depend on.