Skip to content

State is reset on browser refresh - breaks authentication flows #1304

@irevolve

Description

@irevolve

Bug Description

Mesop state is completely reset on browser refresh, making it impossible to maintain authentication tokens or any persistent user data. This renders Mesop unusable for real-world applications requiring user authentication.

Expected Behavior

  • State should persist across browser refreshes within the same session
  • Authentication tokens stored in state should remain available until session expires
  • State should be tied to browser session/Flask session cookies

Actual Behavior

  • All state values are reset to defaults on browser refresh (F5/Ctrl+R)
  • New session files are created with each page reload (when using file backend)
  • Users must re-authenticate after every refresh
  • No state persistence across page reloads

Steps to Reproduce

  1. Create a Mesop app with authentication state:
import mesop as me

@me.stateclass
class AuthState:
    access_token: str = ""
    user_id: str = ""
    is_authenticated: bool = False

def login_success(token: str, user_id: str):
    state = me.state(AuthState)
    state.access_token = token
    state.user_id = user_id 
    state.is_authenticated = True

@me.page(path="/")
def main():
    state = me.state(AuthState)
    if state.is_authenticated:
        me.text(f"Logged in as: {state.user_id}")
    else:
        me.text("Please login")
        me.button("Login", on_click=lambda e: login_success("token123", "user456"))
  1. Run the app and click "Login"
  2. Verify state shows "Logged in as: user456"
  3. Refresh the browser (F5 or Ctrl+R)
  4. Bug: State is reset, shows "Please login" again

Investigation Results

File Backend Behavior:
When using the file backend, each browser refresh creates a new session file:

session_abc123.json  # Created on first visit
session_def456.json  # Created after refresh - previous lost
session_ghi789.json  # Created after another refresh

This confirms that Mesop creates new sessions instead of restoring existing ones.

Tested Solutions (None Work)

✗ All State Backends Tested:

  • Default memory backend
  • File backend
  • All other available backends
  • Result: All backends reset state on refresh

✗ Manual Flask Session Management:

from flask import session

# Attempted workaround - doesn't work
def save_to_flask_session():
    state = me.state(AuthState)
    session['access_token'] = state.access_token
    session.permanent = True

def restore_from_flask_session():
    state = me.state(AuthState)
    if 'access_token' in session:
        state.access_token = session['access_token']
        state.is_authenticated = True

✗ Flask Configuration Attempts:

import os
os.environ['SECRET_KEY'] = 'secret-key'
app.secret_key = 'secret-key'  
app.config['SESSION_PERMANENT'] = True
app.config['PERMANENT_SESSION_LIFETIME'] = 86400 * 30

Environment

  • Mesop version: 1.1.0
  • Python version: 3.x
  • Browser: Chrome/Firefox/Safari (all affected)
  • State backend: Tested all available backends - same issue
  • OS: Windows/macOS/Linux (all affected)

Impact

This bug makes Mesop unusable for production applications because:

  • Users must re-authenticate after every page refresh
  • Shopping carts are lost on refresh
  • Form data is lost on accidental refresh
  • Any user-specific state is permanently volatile
  • Creates terrible user experience

Proposed Solution

State persistence should be tied to browser sessions:

  1. When a page loads, check for existing Flask session cookie
  2. If valid session exists, restore corresponding state
  3. Only create new state when no valid session cookie present
  4. State should persist until session expires (configurable timeout)

Workaround

None found. This appears to be a fundamental architectural limitation that requires a fix in Mesop core.

Additional Context

This is blocking adoption of Mesop for any application requiring:

  • User authentication
  • Shopping carts
  • Form wizards
  • Any persistent user state

Please prioritize this issue as it affects the core usability of the framework for real-world applications.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions