Skip to content

[bug] StopToolSets not called for loaded team #1842

@docker-agent

Description

@docker-agent

🟠 high - bug

File: pkg/server/session_manager.go (line 316)

Code

func (sm *SessionManager) runtimeForSession(ctx context.Context, sess *session.Session, agentFilename, currentAgent string, rc *config.RuntimeConfig) (runtime.Runtime, *sessiontitle.Generator, error) {
	rt, exists := sm.runtimeSessions.Load(sess.ID)
	if exists && rt.runtime != nil {
		return rt.runtime, rt.titleGen, nil
	}

	t, err := sm.loadTeam(ctx, agentFilename, rc)
	if err != nil {
		return nil, nil, err
	}

	// No defer t.StopToolSets(cleanupCtx) here, which can lead to resource leaks
	// if subsequent operations like t.Agent(currentAgent) or runtime.New(t, opts...) fail.

	agent, err := t.Agent(currentAgent)
	if err != nil {
		return nil, nil, err
	}
	sess.MaxIterations = agent.MaxIterations()
	// Initialize thinking state based on whether thinking_budget was explicitly configured
	// in the agent's YAML config. Only enable thinking by default when explicitly configured.
	sess.Thinking = agent.ThinkingConfigured()

	opts := []runtime.Opt{
		runtime.WithCurrentAgent(currentAgent),
		runtime.WithManagedOAuth(false),
		runtime.WithSessionStore(sm.sessionStore),
	}
	run, err := runtime.New(t, opts...)
	if err != nil {
		return nil, nil, err
	}

	titleGen := sessiontitle.New(agent.Model(), agent.FallbackModels()...)

	sm.runtimeSessions.Store(sess.ID, &activeRuntimes{
		runtime:  run,
		session:  sess,
		titleGen: titleGen,
	})

	slog.Debug("Runtime created for session", "session_id", sess.ID)

	return run, titleGen, nil
}

Problem

The sm.loadTeam function returns a *team.Team which might manage resources (like toolsets). In cmd/root/debug.go, where loadTeam is also used, there's a defer cleanup() call to ensure t.StopToolSets is invoked. However, in pkg/server/session_manager.go, runtimeForSession, there is no such deferred cleanup. If an error occurs after sm.loadTeam (e.g., t.Agent(currentAgent) or runtime.New(t, opts...) fails), the t.StopToolSets method on the loaded team.Team object will never be called, potentially leading to resource leaks (e.g., lingering tool processes or connections).

Suggested Fix

Introduce a cleanup function and defer its execution immediately after a successful call to sm.loadTeam. The cleanup function should call t.StopToolSets. This will ensure that StopToolSets is always called when runtimeForSession exits, regardless of any errors that occur later in the function.


Found by nightly codebase scan

Metadata

Metadata

Assignees

No one assigned

    Labels

    automatedIssues created by cagentkind/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions