This call to _rebuildInstances accesses _scopedExecutor without holding the mutex. This is a problem because on shutdown we swap _scopedExecutor with an empty executor. So if there is a step up, and then this lambda starts running but hangs before this line, and then a shutdown happens, _rebuildInstances could be using an empty/invalid _scopedExecutor. The same could possibly happen on step up - step down - step up, but it's a bit harder to follow.
I don't know if it's sufficient to just take the mutex in that callback since that might break other assumptions, so we might have to do some rearranging of things.
Ensure proper synchronization between onStepUp, onStepDown and shutdown.