Skip to content

[Bug] - 500 on /api/new_session_token when it races /api/logout (StaleDataError / ObjectDeletedError on session_tokens) #893

Description

@mrrobertkent

Existing Resources

  • Please search the existing issues for related problems
  • Consult the product documentation : Docs
  • Consult the Troubleshooting Guide : Guide

Describe the bug

POST /api/new_session_token can return HTTP 500 with an unhandled SQLAlchemy exception when it races POST /api/logout.

On logout, the user's row in session_tokens is deleted. If the web UI's periodic session-token refresh (new_session_token) is in-flight or fires within the same few milliseconds, it then operates on the just-deleted row and raises an unhandled exception:

  • sqlalchemy.orm.exc.ObjectDeletedError: Instance '<SessionToken at 0x...>' has been deleted, or its row is otherwise not present.
  • sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table 'session_tokens' expected to update 1 row(s); 0 were matched.

Impact is low (the user is logging out, so the refuted token is moot), but every occurrence logs an [ERROR] root: Unhandled exception occurred traceback and returns a 500 to the client. Deployments with auto_login enabled appear to hit it more often, since logout is immediately followed by re-auth activity.

To Reproduce

  1. Deploy 1.19.0 with an OIDC provider and auto_login enabled.
  2. Sign in and leave a session open long enough for the UI's recurring new_session_token refresh to be scheduled (observed cadence ~5 min).
  3. Log out so that logout lands within milliseconds of a scheduled refresh.
  4. Observe a 500 on POST /api/new_session_token immediately following the POST /api/logout 200.

Observed logs (kasm_api, two separate occurrences, each within ~18 ms of the logout):

[INFO] cherrypy.access: "POST /api/logout HTTP/1.1" 200
[ERROR] root: Unhandled exception occurred
  ...
  File ".../sqlalchemy/orm/loading.py", line 1686, in load_scalar_attributes
    raise orm_exc.ObjectDeletedError(state)
sqlalchemy.orm.exc.ObjectDeletedError: Instance '<SessionToken at 0x...>' has been deleted, or its row is otherwise not present.

[ERROR] root: Unhandled exception occurred
  ...
  File ".../sqlalchemy/orm/persistence.py", line 948, in _emit_update_statements
    raise orm_exc.StaleDataError(
sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table 'session_tokens' expected to update 1 row(s); 0 were matched.
[INFO] cherrypy.access: "POST /api/new_session_token HTTP/1.1" 500

Expected behavior

new_session_token should handle a concurrently-deleted/absent token gracefully — e.g. return 401/redirect to re-authenticate — rather than raising an unhandled exception and returning 500.

Workspaces Version

1.19.0 (kasmweb/*:1.19.0-rolling)

Workspaces Installation Method

Single Server (CE)

Client Browser

  • OS: macOS
  • Browser: Safari 26.3 (also seen with Chromium-based clients)

Workspace Server Information

  • uname -a: Linux kasm-vm 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
  • cat /etc/os-release: Ubuntu 24.04.3 LTS
  • Docker: Server 29.6.1 / API 1.55
  • docker ps | grep kasm: all 8 services on 1.19.0-rolling, healthy

Additional context

Frequency in light single-user use is roughly 2×/24h — only when a logout coincides with a scheduled new_session_token refresh. No user-visible effect (the session is ending), so this is primarily an unhandled-exception/500 that could be caught and returned cleanly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions