I discovered ReassignMenteesJob runs over a thousand times per day for one cswiki former mentee:
[urbanecm@mwlog2002 /srv/mw-log]$ grep ReassignMenteesJob archive/GrowthExperiments.log-20260224 | grep Felix220 | wc -l 1434 [urbanecm@mwlog2002 /srv/mw-log]$ zgrep ReassignMenteesJob archive/GrowthExperiments.log-20260223.gz | grep Felix220 | wc -l 1426 [urbanecm@mwlog2002 /srv/mw-log]$
despite the mentor resigned over a month ago. The job is continuously rescheduled by the mechanism added in T354222: reassignMenteesJob is not able to finish in time when a mentor has too many mentees assigned:
2026-02-23 01:17:59.041757 [9aa82291-b683-49b0-b4f1-0ea8f9900835] mw-jobrunner.codfw.main-546746cf89-x62xw cswiki 1.46.0-wmf.16 GrowthExperiments INFO: GrowthExperiments\Mentorship\ReassignMentees::doReassignMentees processing 0 mentees {"mentees":0,"context.job_type":"reassignMenteesJob"}
2026-02-23 01:17:59.042473 [9aa82291-b683-49b0-b4f1-0ea8f9900835] mw-jobrunner.codfw.main-546746cf89-x62xw cswiki 1.46.0-wmf.16 GrowthExperiments INFO: ReassignMenteesJob finished reassignment with 1 status {"status":true,"context.job_type":"reassignMenteesJob"}
2026-02-23 01:17:59.043524 [9aa82291-b683-49b0-b4f1-0ea8f9900835] mw-jobrunner.codfw.main-546746cf89-x62xw cswiki 1.46.0-wmf.16 GrowthExperiments INFO: ReassignMenteesJob did not reassign all mentees, scheduling new job {"mentor":"Felix220","context.job_type":"reassignMenteesJob"}despite there being zero mentees to process.
What is happening is this:
- The mentor resigned, ReassignMenteesJob fires for the first time. It reassigns the mentees to someone else (logs)
- Once the reassignment finishes, the job checks MentorStore::hasAnyMentees() to see whether there are any mentees remaining (cf. T354222 for why this was added)
- MentorStore::hasAnyMentees() checks for all mentees (including mentees whose accounts were hidden by an oversighter). Felix220 does have one hidden mentee, so this method returns true.
- ReassignMenteesJob fires again. It calls MentorStore::getMenteesByMentor() to find the list of mentees. By default, MentorStore::getMenteesByMentor _ignores_ hidden mentees. For Felix220, it returns an empty array.
- The job doesn't do anything and it returns successfully
- We go back to step 2, and the process repeats...infinitely
This is happening since r1077077: MentorStore::hasAnyMentees: Use more efficient implementation (T376124), which we merged in 2024 (!), which removed the exclusion of hidden users in MentorStore::hasAnyMentees().
WMF-NDA queries confirming the above findings:
{P89004}