Troubleshooting
Common issues and their solutions.
Duplicate Entries in Rondo Club
Section titled “Duplicate Entries in Rondo Club”Symptom: Hundreds of duplicate member posts appear in Rondo Club.
Cause: Sync was run from a local machine. Each machine has its own SQLite database tracking rondo_club_id mappings. The local database doesn’t know about entries created by the server, so it creates new ones instead of updating.
Fix:
# On the servernode tools/delete-duplicates.js --verbose # Dry run firstnode tools/delete-duplicates.js --apply # Delete duplicates (keeps oldest per KNVB ID)Prevention: All sync scripts enforce a server check that blocks local execution. Always sync from root@46.202.155.16:/home/rondo/.
Chromium Won’t Start
Section titled “Chromium Won’t Start”Symptom:
Error: browserType.launch: Executable doesn't existFix: Install/reinstall Chromium:
npx playwright install chromiumIf that doesn’t work, install system dependencies:
sudo apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 \ libcups2 libdrm2 libdbus-1-3 libxkbcommon0 libatspi2.0-0 libxcomposite1 \ libxdamage1 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2TOTP Authentication Fails
Section titled “TOTP Authentication Fails”Symptom: Login to Sportlink fails with invalid OTP code.
Causes and fixes:
-
Wrong secret format:
SPORTLINK_OTP_SECRETmust be the base32 secret key, not the fullotpauth://URL. -
Clock drift: TOTP is time-sensitive. Check server clock:
Terminal window timedatectl statusIf the clock is off, fix with:
Terminal window sudo ntpdate pool.ntp.org
Sync Reports Not Arriving
Section titled “Sync Reports Not Arriving”Symptom: No email reports after cron runs.
Checks:
- Verify Postmark credentials in
.env:Terminal window grep POSTMARK .envgrep OPERATOR_EMAIL .env - Verify sender email is verified in Postmark dashboard under Sender Signatures.
- Test manually:
Terminal window node scripts/send-email.js logs/cron/sync-people-2026-01-15_08-00-00.log people
Lock File Prevents Sync
Section titled “Lock File Prevents Sync”Symptom:
Another people sync is running. Exiting.Cause: A previous sync was interrupted (e.g., server restart, OOM kill) and the flock lock file wasn’t released.
Fix:
rm /home/rondo/.sync-people.lock # Or whichever sync typeNote: This is safe because flock automatically releases on process termination. A stale lock file only persists if the process was killed in an unusual way.
Members Missing from Rondo Club
Section titled “Members Missing from Rondo Club”Symptom: Some members exist in Sportlink but don’t appear in Rondo Club.
Diagnosis:
# Check if member exists in local databasenode tools/show-sportlink-member.js member@example.com
# Check Rondo Club mappingsqlite3 data/rondo-sync.sqlite "SELECT knvb_id, rondo_club_id, last_synced_at FROM rondo_club_members WHERE email = 'member@example.com'"Possible causes:
- No
rondo_club_idyet: Member was downloaded but sync failed. Runscripts/sync.sh peopleto retry. - Invalid
rondo_club_id: The WordPress post was deleted. Fix with:Then re-run sync to recreate the member.Terminal window node tools/verify-rondo-club-data.js --fix --verbose - Member has no email: Sportlink members without an email address may be skipped.
Invalid rondo_club_id Mappings
Section titled “Invalid rondo_club_id Mappings”Symptom: Sync fails with 404 errors for specific members, or members appear to “recreate” every run.
Cause: The WordPress post was deleted outside the sync tool, but the local database still references the old post ID.
Fix:
# Verify which IDs are invalidnode tools/verify-rondo-club-data.js --verbose
# Fix by nullifying invalid IDs (they'll be recreated on next sync)node tools/verify-rondo-club-data.js --fix --verbose
# Or use validate-rondo-club-ids for a simpler checknode tools/validate-rondo-club-ids.js # Dry runnode tools/validate-rondo-club-ids.js --apply # Fix invalid IDsPhotos Not Syncing
Section titled “Photos Not Syncing”Symptom: Member photos show in Sportlink but not in Rondo Club.
Diagnosis:
# Check photo state distributionsqlite3 data/rondo-sync.sqlite "SELECT photo_state, COUNT(*) FROM rondo_club_members GROUP BY photo_state"
# Check consistency between files and databasenode tools/check-photo-consistency.js --verboseCommon issues:
-
Stuck in
pending_download: Photo URL may be expired. Fix:Terminal window # Re-scrape photo URLs via functions syncscripts/sync.sh functions# Then run people sync to download/uploadscripts/sync.sh people -
Files missing for
downloadedstate: Files were cleaned up but state wasn’t updated:Terminal window node tools/check-photo-consistency.js --fix -
Members with photos marked
no_photo: State got out of sync:Terminal window node tools/reset-photo-states.js # Dry runnode tools/reset-photo-states.js --apply # Fix states
Free Fields Missing After Functions Sync
Section titled “Free Fields Missing After Functions Sync”Symptom: FreeScout ID, VOG date, or financial block data disappears from Rondo Club after a daily functions sync.
Cause: This was a critical bug (fixed in commit 9d0136e): when the daily functions sync processed only a subset of members, it used clear + replace on database tables, wiping data for members not in the current run. The fix uses upsert-only for partial runs.
If data was wiped: Run a full functions sync to restore:
ssh root@46.202.155.16 "cd /home/rondo && node pipelines/sync-functions.js --all --verbose"Orphaned Relationships
Section titled “Orphaned Relationships”Symptom: Relationships reference people who no longer exist.
Fix:
# Find orphaned relationshipsnode tools/cleanup-orphan-relationships.js --verbosenode tools/cleanup-orphan-relationships.js --fix # Remove them
# Find duplicate relationshipsnode tools/cleanup-duplicate-relationships.jsNote: As of v2.3, birthdays sync as acf.birthdate on person records and no longer use separate important_date posts.
Laposta Sync Shows Zero Changes
Section titled “Laposta Sync Shows Zero Changes”Symptom: show-laposta-changes shows no pending changes even though data has changed.
Cause: The prepare step may not have run. The sync pipeline runs in order: download → prepare → submit.
Fix:
# Re-prepare Laposta members from latest downloadnpm run prepare-laposta
# Check for changes nownpm run show-laposta-changesDatabase Corruption
Section titled “Database Corruption”Symptom: SQLite errors like “database is locked” or “malformed”.
Recovery options:
-
Database locked: Usually caused by a sync process that didn’t exit cleanly. Kill any lingering Node processes:
Terminal window pkill -f "node sync-" || true -
Database corrupted: The simplest recovery is to delete the database and re-run a full sync. The databases are derived from source systems and can be rebuilt:
Terminal window # Back up firstcp data/rondo-sync.sqlite data/rondo-sync.sqlite.bak# Delete and rebuild (this will create all members as new in Rondo Club!)# Only do this if you're certain - it may cause duplicate entriesrm data/rondo-sync.sqlitescripts/sync.sh allWarning: Deleting
data/rondo-sync.sqliteloses allrondo_club_idmappings. This means the next sync will create new WordPress posts instead of updating existing ones. Usetools/repopulate-rondo-club-ids.jsafterward to restore mappings:Terminal window node tools/repopulate-rondo-club-ids.js --verbose # Dry runnode tools/repopulate-rondo-club-ids.js # Apply