Files
SuperCharged-Claude-Code-Up…/ROMAN_SESSION_ISSUE_ANALYSIS.md
uroma ea7f90519f Add Project Roman session fix analysis and design documentation
This commit includes comprehensive analysis and design documentation
for fixing critical session management issues in manually created projects.

Phase 1 Complete:
- Identified 4 critical errors (SSE null reference, array access,
  race conditions, virtual workingDir mismatch)
- Created detailed root cause analysis
- Designed comprehensive solution with 5 components
- Complete implementation plan with testing strategy

Files added:
- ROMAN_SESSION_ISSUE_ANALYSIS.md - Detailed root cause analysis
- ROMAN_SESSION_FIX_DESIGN.md - Complete solution design
- ROMAN_IMPLEMENTATION_SUMMARY.md - Quick reference guide
- PHASE_1_COMPLETE_REPORT.md - Executive summary

Next: Awaiting AI Engineer review before implementation

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-22 15:19:25 +00:00

7.3 KiB

Project Roman Session Issue - Phase 1 Analysis Report

Problem Statement

When entering project "roman", the following errors occur:

  1. Console errors appear immediately
  2. Sessions do not show in the left sidebar
  3. The pendingSessionAdd approach is fragile and causes race conditions

Root Cause Analysis

Error 1: "Cannot set properties of null (setting 'onopen')"

Location: /home/uroma/obsidian-web-interface/public/claude-ide/sse-client.js:41 Cause: The SSE client attempts to connect to a session before the EventSource object is fully initialized.

this.eventSource = new EventSource(url);
this.eventSource.onopen = () => { ... }  // EventSource may be null here

Why it happens for project "roman":

  • Project "roman" uses a virtual workingDir: /virtual/projects/roman
  • When the project loads, it tries to auto-connect to existing sessions
  • If a session doesn't exist yet or is in a transitional state, EventSource construction fails
  • The code doesn't check if this.eventSource is null before setting onopen

Error 2: "Cannot read properties of undefined (reading 'length')"

Location: Multiple locations in project-manager.js and chat-enhanced.js Cause: Arrays are undefined when operations are performed before data is fully loaded.

Specific instances:

  1. project-manager.js:104 - Sorting sessions array before it's populated
  2. chat-enhanced.js:69 - Rendering sessions when sessionsToRender is undefined
  3. chat-functions.js:72 - Accessing activeProject.sessions when project isn't loaded yet

Error 3: Sessions Not Showing in Left Sidebar

Root Cause: Multiple sources of truth for session data

Sources of truth:

  1. this.projects.sessions - In-memory project state
  2. localStorage - Persisted manually created projects
  3. /claude/api/claude/sessions - API response
  4. this.pendingSessionAdd - Race condition workaround

The race condition flow:

1. createSessionInFolder() called
2. POST /claude/api/claude/sessions - creates session in backend
3. pendingSessionAdd = session - stores in frontend
4. loadProjects() called - fetches from API
5.   - API response doesn't include the new session yet (timing)
6.   - pendingSessionAdd is added to allSessions (workaround)
7. addSessionToProject() called
8. loadProjects() called AGAIN
9. Sessions array reset to empty (localStorage sessions loaded)
10. Session lost!

Error 4: Virtual Working Directory Mismatch

Issue: The project "roman" was created with workingDir: "/home/uroma/obsidian-vault" but should have been "/virtual/projects/roman"

Evidence from logs:

[ProjectManager] workingDir: /home/uroma/obsidian-vault
[ProjectManager] No virtual sessions found for project: roman

The code correctly assigns virtual workingDir on creation (line 473):

const virtualWorkingDir = `/virtual/projects/${projectKey}`;

But the stored localStorage has the wrong value:

{"id":"project-roman","name":"roman","workingDir":"/home/uroma/obsidian-vault",...}

Architectural Issues

1. Multiple Data Sources Without Single Source of Truth

Frontend State (this.projects)
       ↕
localStorage (claude_ide_projects)
       ↕
API Response (/claude/api/claude/sessions)
       ↕
Backend State (claudeService.sessions)

Each can be out of sync with the others.

2. Race Conditions in Initialization

DOMContentLoaded → ProjectManager.initialize()
                        ↓
                  loadManuallyCreatedProjects()
                        ↓
                  loadProjects() ← async fetch
                        ↓
                  renderProjectTabs()
                        ↓
                  switchProject() ← may happen before loadProjects() completes

3. Fragile pendingSessionAdd Pattern

The pendingSessionAdd approach tries to work around timing issues but:

  • Only preserves one session at a time
  • Gets cleared too early or too late
  • Doesn't survive page refreshes
  • Creates complex conditional logic

4. Virtual Session Assignment Logic

The virtual session filtering logic is complex and error-prone:

if (dir.startsWith('/virtual/projects/')) {
    const sessionProjectKey = s.workingDir?.replace('/virtual/projects/', '');
    return sessionProjectKey === key;
}

This assumes a perfect mapping between workingDir and projectKey, but:

  • Manually created projects may have different workingDir values
  • The key transformation (projectKey = projectName.trim().replace(/\s+/g, '-').toLowerCase()) can create mismatches
  • No validation that the workingDir matches the expected pattern

Impact Analysis

User Impact

  • Cannot see sessions in manually created projects
  • Console errors on every page load
  • Sessions may disappear after refresh
  • New sessions may not appear immediately

System Impact

  • Error logs fill up rapidly
  • Multiple unnecessary API calls
  • Inconsistent state across components
  • Difficult to debug due to multiple layers

Proposed Solution Architecture

Phase 2 Design Goals

  1. Single Source of Truth: API is the only source; localStorage is cache only
  2. Event-Driven Updates: Use EventBus for all state changes
  3. Defensive Programming: All array operations check for null/undefined
  4. Virtual Project Consistency: Ensure workingDir matches project identity
  5. Real-Time Logger: Enhanced monitoring and debugging

Solution Components

  1. Fix SSE Client Initialization

    • Add null checks before EventSource property assignment
    • Wrap EventSource construction in try-catch
    • Add connection state validation
  2. Fix Array Access Errors

    • Add null/undefined guards to all array operations
    • Use optional chaining (?.) and nullish coalescing (??)
    • Add validation before sorting/filtering
  3. Implement Proper State Management

    • Remove pendingSessionAdd pattern
    • Use optimistic UI updates with rollback
    • Implement proper loading states
    • Use EventBus for synchronization
  4. Fix Virtual Working Directory Consistency

    • Validate workingDir on project creation
    • Add migration for existing projects
    • Use consistent key generation
  5. Enhanced Real-Time Logger

    • Log all state transitions
    • Track API calls and responses
    • Monitor EventBus traffic
    • Alert on error patterns

Success Metrics

Technical Metrics

  • No console errors on project load
  • Zero race conditions in session creation
  • Consistent state across all components
  • All operations defensive against null/undefined

User Experience Metrics

  • Sessions appear immediately after creation
  • Sessions persist across page refresh
  • Left sidebar always shows current project sessions
  • No flickering or loading states

Next Steps (Phase 2: Design Review)

Before implementing, the following needs AI Engineer review:

  1. Proposed EventBus integration pattern
  2. State synchronization strategy
  3. Virtual project key generation approach
  4. Error handling and recovery mechanisms

Generated: 2026-01-22 Status: Phase 1 Complete - Analysis Complete Next: Phase 2 - Design & AI Engineer Review