# 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. ```javascript 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):** ```javascript const virtualWorkingDir = `/virtual/projects/${projectKey}`; ``` **But the stored localStorage has the wrong value:** ```javascript {"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: ```javascript 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