charmbracelet/crush · error

agent message id missing from context

Error message

agent message id missing from context

What it means

validateAgenticFetchParams finally reads the parent agent message id via tools.GetMessageFromContext(ctx). The fetch sub-run attaches its results to that parent message; a missing id would orphan the tool result, so the validator returns this error after the session check passes.

Source

Thrown at internal/agent/agentic_fetch_tool.go:41

type agenticFetchValidationResult struct {
	SessionID      string
	AgentMessageID string
}

// validateAgenticFetchParams validates the tool call parameters and extracts required context values.
func validateAgenticFetchParams(ctx context.Context, params tools.AgenticFetchParams) (agenticFetchValidationResult, error) {
	if params.Prompt == "" {
		return agenticFetchValidationResult{}, errors.New("prompt is required")
	}

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

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

	return agenticFetchValidationResult{
		SessionID:      sessionID,
		AgentMessageID: agentMessageID,
	}, nil
}

//go:embed templates/agentic_fetch_prompt.md.tpl
var agenticFetchPromptTmpl []byte

func (c *coordinator) agenticFetchTool(_ context.Context, client *http.Client) (fantasy.AgentTool, error) {
	if client == nil {
		transport := http.DefaultTransport.(*http.Transport).Clone()
		transport.MaxIdleConns = 100
		transport.MaxIdleConnsPerHost = 10
		transport.IdleConnTimeout = 90 * time.Second

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Set the message context value (tools.WithMessageContext) in addition to the session value.
  2. Prefer routing the call through the coordinator, which sets both ids automatically.
  3. Pair the two context decorators together in test helpers to prevent recurrence.

Example fix

// before
ctx = tools.WithSessionContext(ctx, sessionID)
// handler fails on message id
// after
ctx = tools.WithSessionContext(ctx, sessionID)
ctx = tools.WithMessageContext(ctx, agentMessageID)
Defensive patterns

Strategy: validation

Validate before calling

if tools.GetMessageFromContext(ctx) == "" {
    return errors.New("agentic fetch requires agent message context")
}

Try / catch

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

Prevention

When it happens

Trigger: Calling the agentic fetch handler with a context that has the session id set but not the message id — usually a hand-rolled dispatcher that only set the session value.

Common situations: Custom tool execution loops; partially migrated test harnesses that set session but not message context; invoking the tool outside the coordinator.

Related errors


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