Production OAuth Error Fix
Problem
Sentry Error: MultipleObjectsReturned in /api/auth/google/ endpoint
Root Cause: Database has duplicate SocialApp entries for Google OAuth provider. Django-allauth expects exactly one SocialApp per provider.
# Error in allauth/socialaccount/adapter.py:299
apps = [<SocialApp: Google>, <SocialApp: >] # 2 Google apps found!
raise MultipleObjectsReturned # Can't decide which to use
Solution: Management Command
Created automatic cleanup command: users/management/commands/fix_duplicate_social_apps.py
Features
- Detects duplicates for all OAuth providers (Google, Facebook, Microsoft)
- Keeps valid apps with credentials, deletes invalid/duplicate ones
- Supports
--dry-runmode for safe preview - Supports
--providerflag for specific providers - Handles 3 scenarios intelligently:
- One valid app: Keeps valid, deletes invalid duplicates
- Multiple valid apps: Keeps first valid, deletes rest
- No valid apps: Keeps first for admin to configure, deletes rest
How to Fix Production
Option 1: Run Management Command (Recommended)
Step 1: Preview changes (dry-run)
# SSH into production server
ssh [email protected]
# Navigate to project directory
cd /path/to/av
# Preview what would be deleted
python manage.py fix_duplicate_social_apps --dry-run
Example output:
Checking GOOGLE apps...
⚠ Found 2 google apps (should be 1)
1. ID=1, Name='Google', Client ID=Yes, Secret=Yes - ✓ Valid
2. ID=2, Name='', Client ID=No, Secret=No - ✗ Invalid/Empty
Strategy: Keep valid app (ID=1), delete 1 invalid
[DRY RUN] Would delete: ID=2, Name=''
============================================================
[DRY RUN] Would delete 1 duplicate apps
Run without --dry-run to actually delete
Step 2: Execute actual fix
Expected output:
Checking GOOGLE apps...
⚠ Found 2 google apps (should be 1)
1. ID=1, Name='Google', Client ID=Yes, Secret=Yes - ✓ Valid
2. ID=2, Name='', Client ID=No, Secret=No - ✗ Invalid/Empty
Strategy: Keep valid app (ID=1), delete 1 invalid
Deleting: ID=2, Name=''
============================================================
✓ Deleted 1 duplicate apps
Step 3: Verify fix
# Check that only 1 Google app remains
python manage.py shell
>>> from allauth.socialaccount.models import SocialApp
>>> SocialApp.objects.filter(provider='google').count()
1 # Should be exactly 1
>>> exit()
# Test OAuth login
curl -X POST https://api.avai.maakeetoo.com/api/auth/google/ \
-H "Content-Type: application/json" \
-d '{"access_token": "valid-google-token"}'
Option 2: Django Admin UI
- Navigate to:
https://api.avai.maakeetoo.com/admin/socialaccount/socialapp/ - Login with superuser credentials
- Look for duplicate Google entries (you'll see 2+ rows)
- Identify which one has valid
Client IDandSecret - Delete the invalid/duplicate entries (keep the valid one)
Option 3: Django Shell (Manual)
from allauth.socialaccount.models import SocialApp
# List all Google apps
google_apps = SocialApp.objects.filter(provider='google')
for app in google_apps:
print(f"ID={app.id}, Name='{app.name}', ClientID={'Yes' if app.client_id else 'No'}")
# Delete specific invalid app by ID (replace 2 with actual ID)
SocialApp.objects.get(id=2).delete()
# Verify only 1 remains
print(SocialApp.objects.filter(provider='google').count()) # Should be 1
Why Local Test Showed No Duplicates
The management command dry-run in local Docker showed:
Explanation:
- Local environment: Uses SOCIALACCOUNT_PROVIDERS settings (environment variables), no database SocialApp entries
- Production environment: Uses database SocialApp entries, which have duplicates
The error only exists in production database. The command works correctly - it just had nothing to clean in the local environment.
Prevention
To prevent future duplicates:
- Never create duplicate SocialApps: Use Django admin carefully
- Check before creating:
- Use fixtures for deployment: Create SocialApps via data migrations, not manual admin
- Consider using settings-based providers: Configure OAuth via
SOCIALACCOUNT_PROVIDERSinsettings.pyinstead of database entries
Post-Fix Actions
After fixing the duplicate:
- ✅ Test OAuth login - Verify users can authenticate with Google
- ✅ Monitor Sentry - Check that
MultipleObjectsReturnederror stops occurring - ✅ Document credentials - Ensure Google OAuth credentials are documented for disaster recovery
- ⚠️ Review other providers - Check if Facebook/Microsoft have duplicates too
Related Files
- Management command:
users/management/commands/fix_duplicate_social_apps.py - OAuth configuration:
core/settings.py(lines 342-388) - Admin interface: Django admin at
/admin/socialaccount/socialapp/ - Sentry error: Check
/api/auth/google/endpoint errors