ruvnet/ruflo · error

Session not found: ${sessionId}

Error message

Session not found: ${sessionId}

What it means

SessionManager.terminateSession() looks the session up in an in-memory Map and throws when sessionId is absent. Sessions are created by createSession() (which assigns a generated secure ID) and tracked per manager instance, so unknown, already-terminated-but-removed, or cross-instance IDs fail here.

Source

Thrown at v3/@claude-flow/shared/src/core/orchestrator/session-manager.ts:127

    return this.sessions.get(sessionId);
  }

  getActiveSessions(): IAgentSession[] {
    return Array.from(this.sessions.values()).filter(
      session => session.status === 'active' || session.status === 'idle',
    );
  }

  getSessionsByAgent(agentId: string): IAgentSession[] {
    return Array.from(this.sessions.values()).filter(
      session => session.agentId === agentId,
    );
  }

  async terminateSession(sessionId: string): Promise<void> {
    const session = this.sessions.get(sessionId);
    if (!session) {
      throw new Error(`Session not found: ${sessionId}`);
    }

    session.status = 'terminated';
    session.endTime = new Date();

    const duration = session.endTime.getTime() - session.startTime.getTime();

    this.eventBus.emit(SystemEventTypes.SESSION_TERMINATED, {
      sessionId,
      agentId: session.agentId,
      duration,
    });

    // Clean up profile reference
    this.sessionProfiles.delete(sessionId);

    // Persist sessions asynchronously
    this.persistSessions().catch(() => {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Check sessionManager.getSession(sessionId) before terminating; treat undefined as already gone
  2. Make teardown idempotent by catching and ignoring 'Session not found'
  3. When restoring persisted sessions after restart, re-register them before allowing terminateSession calls

Example fix

// before
await sessionManager.terminateSession(sessionId);

// after
if (sessionManager.getSession(sessionId)) {
  await sessionManager.terminateSession(sessionId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (sessionManager.getSession(sessionId)?.status === 'active') {
  await sessionManager.terminateSession(sessionId);
}

Type guard

const session = sessionManager.getSession(sessionId);
if (session) {
  // safe to terminate
}

Try / catch

try {
  await sessionManager.terminateSession(sessionId);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Session not found')) return;
  throw e;
}

Prevention

When it happens

Trigger: Calling terminateSession() with an ID not returned by createSession(); terminating the same session twice in cleanup paths; passing an ID obtained from getSessionsByAgent() of a different SessionManager instance.

Common situations: Logout/cleanup code that runs twice; session IDs persisted to disk (sessions.json) and reused after the process restarted with an empty in-memory map; multi-worker setups where each worker has its own SessionManager.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/2512d4ec701af5c7. Report an issue: GitHub.