Flash message persistance seems to only work with a 302

I’m working on getting some flash messages to appear correctly after a failed captcha. I have a CaptchPlug that will validate the captcha and if the user gets it wrong or there was some error with the verification process, it’ll put a flash message up telling the user what happened.

I have this code here that runs on failure:

        |> Controller.put_flash(
          "There was an error verifying you're not a robot. Please try again."
        |> Conn.put_status(:conflict)
        |> Controller.text("")
        |> Conn.halt()

The client side code makes a JS http request to an endpoint and it will get back a 409 (conflict) and trigger a page reload. I expect the reloaded page to show the flash message. However when the page reloads, there’s no message to be seen. BUT when I change the put_status to return a 302 instead, I can do the exact same thing as I did with the 409 (without the browser reloading itself) and reload the page and the flash message appears. The only difference between the two tests is a 409 vs. a 302 status code (browser is performing the exact same requests either way), but the message doesn’t appear unless I use a 302.

Is there some logic that surrounds flash messages and status codes? Is there a better way to get at what I’m trying to do?


Only 3xx status codes will put the flash message in the session. All other ones are meant to render the flash message within the request, which set the flash message.

Thanks. Ended up returning a 300 and letting the client JS catch/handle it to reload the page.