Skip to content

Conversation

@Lokimorty
Copy link

⚠️ Critical: This is a defensive fix for a deeper data integrity issue

Problem

Starting around November 14, 2025, users began experiencing crashes on the Sessions tab with RangeError: Invalid time value at Date.toISOString(). This appears to be a data integrity issue, not a code regression - sessions are returning null values for date fields.

Solution

Adds defensive null checks across session components to prevent crashes and includes development-mode observability logging to track the scope of the problem.

Changes

  • Added null validation in SessionsTable, SessionInfo, SessionActivity, and DateDistance components
  • Development-only console.error logs when null dates are encountered (with context like sessionId, eventId)
  • Display "—" placeholder when dates are missing instead of crashing

What Needs Investigation

This PR prevents crashes but does NOT fix the underlying data corruption. Immediate actions needed:

  1. Database audit for sessions/events with null date fields
  2. Check for changes around Nov 14 (migrations, deployments, imports)
  3. Consider adding React Error Boundaries, API response validation, and user-visible warnings

- Add null validation in SessionsTable, SessionInfo, SessionActivity, and DateDistance
- Log missing date fields in development mode only
- Display '—' placeholder when dates are null instead of crashing
- Addresses RangeError: Invalid time value on Sessions tab
@vercel
Copy link

vercel bot commented Nov 14, 2025

@Lokimorty is attempting to deploy a commit to the umami-software Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Nov 14, 2025

Greptile Overview

Greptile Summary

Added defensive null checks across session-related components to prevent RangeError: Invalid time value crashes when date fields are unexpectedly null.

  • Added early null checks in SessionsTable, SessionInfo, and SessionActivity before passing dates to DateDistance component
  • Added validation in DateDistance component itself as a second layer of defense
  • Displays "—" placeholder for missing dates instead of crashing
  • Includes development-mode logging to help track and diagnose the underlying data integrity issue
  • Minor cleanup: removed empty dist: {} from pnpm-lock.yaml

This is a defensive fix that prevents user-facing crashes but does not address the root cause of null dates appearing in the database.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - it's a well-implemented defensive fix that prevents crashes without introducing new issues
  • The changes are defensive and safe: they add null checks before processing dates, gracefully handle missing data by displaying placeholders, and include helpful logging for debugging. The implementation is consistent across all affected components and uses appropriate validation methods
  • No files require special attention - all changes follow the same defensive pattern and are implemented correctly

Important Files Changed

File Analysis

Filename Score Overview
src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx 5/5 Added null check for row.createdAt before passing to DateDistance, displays "—" when missing, includes dev-mode logging
src/app/(main)/websites/[websiteId]/sessions/SessionInfo.tsx 5/5 Added null checks for data.lastAt and data.firstAt before rendering DateDistance, displays "—" placeholder when missing, includes dev-mode logging
src/app/(main)/websites/[websiteId]/sessions/SessionActivity.tsx 5/5 Added null check for createdAt in event map, returns null (skips event) when missing, includes dev-mode logging with event context
src/components/common/DateDistance.tsx 5/5 Added validation for null/undefined dates and invalid date objects using isNaN(date.getTime()), displays "—" for invalid dates, includes dev-mode logging

Sequence Diagram

sequenceDiagram
    participant User
    participant SessionsTable
    participant SessionInfo
    participant SessionActivity
    participant DateDistance
    participant API

    User->>SessionsTable: View sessions list
    API->>SessionsTable: Return session data (may have null dates)
    
    alt createdAt is null
        SessionsTable->>SessionsTable: Log error (dev mode)
        SessionsTable->>User: Display "—"
    else createdAt exists
        SessionsTable->>DateDistance: Pass Date object
        DateDistance->>DateDistance: Validate date with isNaN()
        alt Invalid date
            DateDistance->>DateDistance: Log error (dev mode)
            DateDistance->>User: Display "—"
        else Valid date
            DateDistance->>User: Display relative time
        end
    end

    User->>SessionInfo: View session details
    API->>SessionInfo: Return session data (may have null dates)
    
    alt lastAt/firstAt is null
        SessionInfo->>SessionInfo: Log error (dev mode)
        SessionInfo->>User: Display "—"
    else lastAt/firstAt exists
        SessionInfo->>DateDistance: Pass Date object
        DateDistance->>User: Display relative time
    end

    User->>SessionActivity: View session activity
    API->>SessionActivity: Return events (may have null createdAt)
    
    alt createdAt is null
        SessionActivity->>SessionActivity: Log error (dev mode)
        SessionActivity->>SessionActivity: Skip event (return null)
    else createdAt exists
        SessionActivity->>User: Display event with timestamp
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@Lokimorty Lokimorty closed this Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant