Node.js/Express/Jade + Passport.js failureRedirect incorrectly rendering page

On a failed authentication at /login, passport.js saves an error message using failureFlash and redirects to /login (the same page). The sent HTML is correct (i.e., includes the failureFlash message), but is rendered incorrectly on the client side as 'undefined,' despite (in the Jade template) being in logic that guarantees it's defined. My route for the HTML (GET /login) and for the submission (POST /login) use the same URL; could that be part of the problem? The whole code-base can be found here.


app.js local strategy

passport.use(new LocalStrategy(
    function(username, password, done) {
        // asynchronous verification, for effect...
        process.nextTick(function () {
            var user = {'id': 1};
            if(username !== "asdf") {
                return done(null, false, { error: 'Unknown user '+username+'.'});
            }else if(password !== "zxcv") {
                return done(null, false, { error: 'Invalid password.'})
            }

            return done(null, user);
    });
  }
));

app.js login GET route

app.get('/login', function(req, res) {
    var m1 = req.flash('error')[0]
    console.log(m1)
    res.render('login', { user: req.user, message: String(m1), sample: "Sanity check."});
});

app.js login POST route

app.post('/login', 
    passport.authenticate('local', { failureRedirect: '/login', failureFlash: 'THIS IS A SANITY CHECK ERROR', successFlash: 'Welcome!' }),
    function(req, res) {
        console.log('User login successful.');
        var redirect_to = req.session.redirect_to || '/'
        delete req.session.redirect_to;
        res.send({redirect: String(redirect_to)})
        //res.redirect(200, redirect_to);

    });
    app.get('/logout', function(req, res){
        req.logout();
        res.redirect(200, '/');
    });

client_login.js served with /login's HTML

$(document).on('pageinit', function() {
    $(document).on('click', '#submit', function() {
        if($('#username').val().length > 0 && $('#password').val().length > 0){
            // Send data to server through the ajax call
            // action is functionality we want to call and outputJSON is our data
            $.ajax({
                url: '/login',
                data: {action : 'login', username : $('#username').val(), password : $('#password').val()},
                type: 'post',
                async: 'true',
                dataType: 'json'
            })
            .done(function (result) {
                console.log('Done!');
                window.location.replace(result.redirect);
            })
            .always(function (result) {
                console.log('Always!');
            })
            .fail(function (request,error) {
                console.log('Fail!');
                // This callback function will trigger on unsuccessful action
                //alert('Network error has occurred please try again!');
            })
        } else {
            if($('#username').val().length <= 0 && $('#password').val().length > 0) {
                alert('Please fill in your username.');
            } else if($('#username').val().length > 0 && $('#password').val().length <= 0) {
                alert('Please fill in your password.');
            } else {
                alert('Please fill in your username and password.');    
            }
        }
        return false; // cancel original event to prevent form submitting
    })
})

login.jade

extends layout

block content
    h1= title


    if locals.expose.exists['client_login.js']
        script(src='/dist/javascripts/client_login.js')
    else
        script(src='/javascripts/client_login.js')


    div(style='max-width: 300px; margin:0 auto')
        p(style='text-align: left') Please login to continue.
        - if(typeof message !== 'undefined' && message.length > 0)
            p Error! #{message}
        p= sample

        form(role='form', action='/login', method='post')
            .form-group
                input.form-control(type='text', data-clear-btn="true", name="username", id="username", value="", placeholder='Username')
            .form-group
                input.form-control(type='password', data-clear-btn="true", name="password", id="password", value="", placeholder='Password')
            .form-group
                button(type='submit', name='submit', id='submit' class="ui-btn ui-corner-all") Submit

HTML as sent from the server at bottom, rendered page at top. Note "undefined" vs "THIS IS A SANITY CHECK ERROR". Also note this project uses jQuery Mobile. Any ideas on what might be causing this behavior? The page's javascript shouldn't touch it, but there's also no visible flickering on redirect, which is good, but makes me suspicious.

HTML as sent from the server at bottom, rendered page at top. Note "undefined" vs "THIS IS A SANITY CHECK ERROR".

Well, I'm dense. You can't redirect in response to an AJAX post.

So, I modified the AJAX post as below:

        .fail(function (request,error) {
            console.log('Fail!');
            window.location.replace(window.location.href);

        })

The window.location.replace(window.location.href); feels a little clumsy & there is probably a better way to approach a page refresh, but for the moment, this works.

... This is why I post here. Rubber ducky debugging works.