charmbracelet/crush · error

session id missing from context

Error message

session id missing from context

What it means

The 'agent' tool's Execute handler reads the current session id from the context via tools.GetSessionFromContext(ctx). Sub-agent runs must be attributed to a parent session for persistence and pub/sub; if the context carries no session id the tool cannot proceed and returns this error.

Source

Thrown at internal/agent/agent_tool.go:50

	if err != nil {
		return nil, err
	}

	agent, err := c.buildAgent(ctx, prompt, agentCfg, true)
	if err != nil {
		return nil, err
	}
	return fantasy.NewParallelAgentTool(
		AgentToolName,
		agentToolDescription,
		func(ctx context.Context, params AgentParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
			if params.Prompt == "" {
				return fantasy.NewTextErrorResponse("prompt is required"), nil
			}

			sessionID := tools.GetSessionFromContext(ctx)
			if sessionID == "" {
				return fantasy.ToolResponse{}, errors.New("session id missing from context")
			}

			agentMessageID := tools.GetMessageFromContext(ctx)
			if agentMessageID == "" {
				return fantasy.ToolResponse{}, errors.New("agent message id missing from context")
			}

			return c.runSubAgent(ctx, subAgentParams{
				Agent:          agent,
				SessionID:      sessionID,
				AgentMessageID: agentMessageID,
				ToolCallID:     call.ID,
				Prompt:         params.Prompt,
				SessionTitle:   "New Agent Session",
			})
		},
	), nil
}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Invoke the agent tool through the standard coordinator/agent loop, which sets the session context value.
  2. In custom callers, wrap the context with tools.WithSessionContext(ctx, sessionID) before Execute.
  3. Fix tests to use the same context helpers the production path uses.

Example fix

// before
resp, err := tool.Execute(ctx, params) // ctx has no session
// after
ctx = tools.WithSessionContext(ctx, sessionID)
resp, err := tool.Execute(ctx, params)
Defensive patterns

Strategy: validation

Validate before calling

if tools.GetSessionFromContext(ctx) == "" {
    return errors.New("session context required before executing agent tool")
}

Try / catch

resp, err := tool.Execute(ctx, params)
if err != nil && strings.Contains(err.Error(), "session id missing from context") {
    ctx = tools.WithSessionContext(ctx, sessionID)
    resp, err = tool.Execute(ctx, params)
}

Prevention

When it happens

Trigger: Executing the agent tool with a context that was never populated by tools.WithSession (empty return from GetSessionFromContext) — e.g. invoking the tool directly in tests or via MCP plumbing without the session context decorators the normal agent loop installs.

Common situations: Custom tool runners or tests that call tool.Execute with a bare context.Background(); third-party integrations invoking tools outside the coordinator's dispatch path.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/77d0db6a7b2cb7ee. Report an issue: GitHub.