Skip to content

fix: quota-exceeded users can still start sessions (stopped after 3min) #173

@nikolanovoselec

Description

@nikolanovoselec

Bug

When a user reaches 100% of their monthly compute quota, they can still click "+ New Session" and start a container. The session runs for ~3 minutes (startup guard period) until the Timekeeper KV updates and the quota check kicks in, at which point the session is stopped and the user is kicked back to the dashboard.

The user can repeat this indefinitely — each cycle wastes container resources and gives ~3 minutes of free compute.

Expected Behavior

Users who have exceeded their quota should be blocked from starting new sessions entirely, similar to how trial users cannot start more than 1 concurrent session. The "+ New Session" button should be disabled and show a message like "Monthly quota exceeded — upgrade to continue."

Current Flow (broken)

  1. User reaches 100% quota
  2. User clicks "+ New Session" — container starts
  3. Container runs for ~3 min (startup guard protects new sessions from immediate quota kill)
  4. Timekeeper ping returns quotaExceeded: true — container stopped via SIGTERM
  5. User lands on dashboard — can repeat from step 2

Expected Flow

  1. User reaches 100% quota
  2. batch-status returns quota state — frontend disables "+ New Session"
  3. POST /api/container/start rejects with 402 QUOTA_EXCEEDED (server-side guard)
  4. User sees upgrade CTA

Where to Fix

  • Frontend: isAtUsageQuota() already exists in session-usage.ts and disables the button — verify it's wired correctly to the "New Session" button state
  • Backend: validateSessionAndCheckLimits() in container lifecycle should check quota BEFORE starting the container, not rely on Timekeeper ping after startup
  • REQ-SUB-007 (quota enforcement) and REQ-SUB-008 (mid-session quota stop) — the gap is between these two: pre-start enforcement needs to be airtight

References

  • web-ui/src/stores/session-usage.tsisAtUsageQuota()
  • src/routes/container/lifecycle.tsvalidateSessionAndCheckLimits()
  • src/timekeeper/index.ts — quota ping handler
  • sdd/subscription.md — REQ-SUB-007, REQ-SUB-008

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions