Skip to content

Troubleshooting

Common issues and their solutions.

Symptom: A Rondo Club PATCH fails with rest_invalid_param for the acf parameter even though clearing a field is intentional.

Cause: ACF select, radio, and button-group REST schemas accept null for an empty value but reject an empty string when "" is not one of the configured choices.

Fix: Send null, not "", when clearing one of these fields. Keep the detailed data.params value from the WordPress error in the sync report so the offending field remains visible.


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:

Terminal window
# On the server
node tools/delete-duplicates.js --verbose # Dry run first
node 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/.


Symptom:

Error: browserType.launch: Executable doesn't exist

Fix: Install/reinstall Chromium:

Terminal window
npx playwright install chromium

If that doesn’t work, install system dependencies:

Terminal window
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 libasound2

Symptom: Login to Sportlink fails with invalid OTP code.

Causes and fixes:

  1. Wrong secret format: SPORTLINK_OTP_SECRET must be the base32 secret key, not the full otpauth:// URL.

  2. Clock drift: TOTP is time-sensitive. Check server clock:

    Terminal window
    timedatectl status

    If the clock is off, fix with:

    Terminal window
    sudo ntpdate pool.ntp.org

Symptom: No email reports after cron runs.

Checks:

  1. Verify Lettermint credentials in .env:
    Terminal window
    grep LETTERMINT .env
    grep OPERATOR_EMAIL .env
  2. Verify sender email is verified in the Lettermint dashboard.
  3. Test manually:
    Terminal window
    node scripts/send-email.js logs/cron/sync-people-2026-01-15_08-00-00.log people

Symptom:

Another people sync is running. Exiting.

Cause: A previous sync process is still alive and holds the flock, possibly because a browser session survived an earlier login failure.

Fix:

Terminal window
lsof /home/rondo/.sync-people.lock
# Inspect the listed process and stop it only when it is confirmed stale.

The empty lock file itself is harmless: flock releases automatically when the holder exits. Deleting a file that is still locked does not release the live flock and can let a second process lock a new inode, so never remove it as a substitute for stopping a confirmed stale process.

If the dashboard says Started but no new run appears, inspect the corresponding file under logs/dashboard-launch/. A pipeline can be blocked by a process that still holds the flock even after its run summary was written. Sportlink browser sessions close themselves when initial login fails, and the dashboard checks for an immediate sync.sh exit before confirming a launch. On older deployments, verify the lock holder with lsof .sync-<type>.lock and stop only the confirmed stale process; deleting the lock file does not release a live flock.


Symptom: Some members exist in Sportlink but don’t appear in Rondo Club.

Diagnosis:

Terminal window
# Check if member exists in local database
node tools/show-sportlink-member.js member@example.com
# Check Rondo Club mapping
sqlite3 data/rondo-sync.sqlite "SELECT knvb_id, rondo_club_id, last_synced_at FROM rondo_club_members WHERE email = 'member@example.com'"

Possible causes:

  1. No rondo_club_id yet: Member was downloaded but sync failed. Run scripts/sync.sh people to retry.
  2. Invalid rondo_club_id: The WordPress post was deleted. Fix with:
    Terminal window
    node tools/verify-rondo-club-data.js --fix --verbose
    Then re-run sync to recreate the member.
  3. Member has no email: Sportlink members without an email address may be skipped.

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:

Terminal window
# Verify which IDs are invalid
node 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 check
node tools/validate-rondo-club-ids.js # Dry run
node tools/validate-rondo-club-ids.js --apply # Fix invalid IDs

Symptom: Member photos show in Sportlink but not in Rondo Club.

Diagnosis:

Terminal window
# Check photo state distribution
sqlite3 data/rondo-sync.sqlite "SELECT photo_state, COUNT(*) FROM rondo_club_members GROUP BY photo_state"
# Check consistency between files and database
node tools/check-photo-consistency.js --verbose

Common issues:

  1. Stuck in pending_download: Photo URL may be expired. Fix:

    Terminal window
    # Re-scrape photo URLs via functions sync
    scripts/sync.sh functions
    # Then run people sync to download/upload
    scripts/sync.sh people
  2. Files missing for downloaded state: Files were cleaned up but state wasn’t updated:

    Terminal window
    node tools/check-photo-consistency.js --fix
  3. Members with photos marked no_photo: State got out of sync:

    Terminal window
    node tools/reset-photo-states.js # Dry run
    node tools/reset-photo-states.js --apply # Fix states

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:

Terminal window
ssh root@46.202.155.16 "cd /home/rondo && node pipelines/sync-functions.js --all --verbose"

Symptom: Relationships reference people who no longer exist.

Fix:

Terminal window
# Find orphaned relationships
node tools/cleanup-orphan-relationships.js --verbose
node tools/cleanup-orphan-relationships.js --fix # Remove them
# Find duplicate relationships
node tools/cleanup-duplicate-relationships.js

Note: As of v2.3, birthdays sync as acf.birthdate on person records and no longer use separate important_date posts.


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:

Terminal window
# Re-prepare Laposta members from latest download
npm run prepare-laposta
# Check for changes now
npm run show-laposta-changes

Symptom: SQLite errors like “database is locked” or “malformed”.

Recovery options:

  1. 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
  2. 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 first
    cp 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 entries
    rm data/rondo-sync.sqlite
    scripts/sync.sh all

    Warning: Deleting data/rondo-sync.sqlite loses all rondo_club_id mappings. This means the next sync will create new WordPress posts instead of updating existing ones. Use tools/repopulate-rondo-club-ids.js afterward to restore mappings:

    Terminal window
    node tools/repopulate-rondo-club-ids.js --verbose # Dry run
    node tools/repopulate-rondo-club-ids.js # Apply