O código acima funciona, meus dados estavam ruins. Como escrevi no comentário acima, alguns dos documentos tinham isFoo como uma String (não booleana) e é por isso que eu estava vendo os resultados mistos.
Eu tive que mudar o tipo do campo de String para Boolean, então tentei isso:
db.users.find( { 'isFoo' : { $exists : true } } ).forEach( function (x) { x.isFoo = new Boolean(x.isFoo); db.users.save(x); });
Mas isso acabou de transformar todos os campos isFoo em Objetos.
Vendo que eu estava realmente cansado de lidar com esse problema, usei o seguinte para definir todos os campos isFoo como false e apenas lidar com as alterações manualmente.
db.users.find( { 'isFoo' : { $exists : true } } ).forEach( function (x) { x.isFoo = false; db.users.save(x); });
Isso era muito irritante.