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>
7.3 KiB
Project Roman Session Issue - Phase 1 Analysis Report
Problem Statement
When entering project "roman", the following errors occur:
- Console errors appear immediately
- Sessions do not show in the left sidebar
- The
pendingSessionAddapproach 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.eventSourceis null before settingonopen
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:
project-manager.js:104- Sorting sessions array before it's populatedchat-enhanced.js:69- Rendering sessions whensessionsToRenderisundefinedchat-functions.js:72- AccessingactiveProject.sessionswhen 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:
this.projects.sessions- In-memory project statelocalStorage- Persisted manually created projects/claude/api/claude/sessions- API responsethis.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
- Single Source of Truth: API is the only source; localStorage is cache only
- Event-Driven Updates: Use EventBus for all state changes
- Defensive Programming: All array operations check for null/undefined
- Virtual Project Consistency: Ensure workingDir matches project identity
- Real-Time Logger: Enhanced monitoring and debugging
Solution Components
-
Fix SSE Client Initialization
- Add null checks before EventSource property assignment
- Wrap EventSource construction in try-catch
- Add connection state validation
-
Fix Array Access Errors
- Add null/undefined guards to all array operations
- Use optional chaining (
?.) and nullish coalescing (??) - Add validation before sorting/filtering
-
Implement Proper State Management
- Remove
pendingSessionAddpattern - Use optimistic UI updates with rollback
- Implement proper loading states
- Use EventBus for synchronization
- Remove
-
Fix Virtual Working Directory Consistency
- Validate workingDir on project creation
- Add migration for existing projects
- Use consistent key generation
-
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:
- Proposed EventBus integration pattern
- State synchronization strategy
- Virtual project key generation approach
- Error handling and recovery mechanisms
Generated: 2026-01-22 Status: Phase 1 Complete - Analysis Complete Next: Phase 2 - Design & AI Engineer Review