charmbracelet/crush · error

agent error: %w

Error message

agent error: %w

What it means

Handler for generic agent error events: when an Error-type event arrives matching this session, the stream stops and wraps the event's error object. Unlike 438 this is a structured error event during the run, not the final RunComplete status.

Source

Thrown at internal/cmd/run.go:452

		}
		// Attribute the error to our run before treating it as
		// fatal. Async errors from an unrelated workspace run share
		// this channel, so a foreign failure must not abort us:
		//   - if the event carries a RunID, it is the authoritative
		//     correlator: it must match our run exactly, otherwise it
		//     belongs to a different request and we ignore it.
		//   - if the event carries no RunID (older server), fall back
		//     to SessionID: it must be present and match our session,
		//     otherwise we ignore it.
		if e.Payload.RunID != "" {
			if e.Payload.RunID != s.runID {
				return false, nil
			}
		} else if e.Payload.SessionID == "" || e.Payload.SessionID != s.sessionID {
			return false, nil
		}
		stop()
		return true, fmt.Errorf("agent error: %w", e.Payload.Error)
	}
	return false, nil
}

// waitForAgent polls GetAgentInfo until the agent is ready, with a
// timeout.
func waitForAgent(ctx context.Context, c *client.Client, wsID string) error {
	timeout := time.After(30 * time.Second)
	for {
		info, err := c.GetAgentInfo(ctx, wsID)
		if err == nil && info.IsReady {
			return nil
		}
		select {
		case <-timeout:
			if err != nil {
				return fmt.Errorf("timeout waiting for agent: %w", err)
			}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Inspect the wrapped e.Payload.Error for the root cause
  2. Retry the run for transient network/stream failures
  3. Disable or fix failing MCP servers if the error mentions a tool
  4. Check context cancellation handling if errors appear after Ctrl-C/timeout

Example fix

// before: treat cancellation as an error
return true, fmt.Errorf("agent error: %w", e.Payload.Error)
// after
if errors.Is(e.Payload.Error, context.Canceled) {
	return true, nil // user cancelled, not a real failure
}
return true, fmt.Errorf("agent error: %w", e.Payload.Error)
Defensive patterns

Strategy: try-catch

Try / catch

stop()
if errors.Is(e.Payload.Error, context.Canceled) || errors.Is(e.Payload.Error, context.DeadlineExceeded) {
	return true, nil // treat cancellation as normal exit
}
return true, fmt.Errorf("agent error: %w", e.Payload.Error)

Prevention

When it happens

Trigger: An error event (Payload of event type Error) is published for this session while runStream.handle() is looping — provider stream failure mid-run, internal agent panic, tool subsystem failure, or MCP tool error escalated to the agent.

Common situations: Network drop mid-stream from the LLM provider; MCP server crash during tool call; context cancellation from the user (Ctrl-C) surfacing as an agent error; provider streaming protocol error.

Related errors


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