charmbracelet/crush · error

agent message id missing from context

Error message

agent message id missing from context

What it means

The 'agent' tool handler also requires the parent assistant message id from context via tools.GetMessageFromContext(ctx). The sub-agent's output is recorded as part of that parent message (tool result linkage); without it, message bookkeeping would break, so the tool returns this error.

Source

Thrown at internal/agent/agent_tool.go:55

	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. Run the tool through the normal coordinator dispatch, which attaches the agent message id.
  2. In custom callers, set the message context (tools.WithMessageContext / equivalent) alongside the session id.
  3. Ensure both session and message ids are set together — the checks are sequential and both are required.

Example fix

// before
ctx = tools.WithSessionContext(ctx, sessionID)
// after
ctx = tools.WithSessionContext(ctx, sessionID)
ctx = tools.WithMessageContext(ctx, agentMessageID)
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

resp, err := tool.Execute(ctx, params)
if err != nil && strings.Contains(err.Error(), "agent message id missing from context") {
    ctx = tools.WithMessageContext(ctx, agentMessageID)
    resp, err = tool.Execute(ctx, params)
}

Prevention

When it happens

Trigger: Same as error 2 but for the message id: executing the agent tool with a context lacking the message value set by the agent loop (empty GetMessageFromContext result).

Common situations: Direct tool invocation in tests or scripts; custom execution paths that set the session but forget the message context; re-implementations of the tool dispatch loop.

Related errors


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