charmbracelet/crush · error
failed to send message: %w
Error message
failed to send message: %w
What it means
Wraps errors from c.SendMessage(), which submits the user prompt to the agent for the session. Thrown when the message cannot be enqueued/dispatched to the session agent.
Source
Thrown at internal/cmd/run.go:265
}
}
} else {
slog.Info("Created session for non-interactive run", "session_id", sess.ID)
}
events, err := c.SubscribeEvents(ctx, ws.ID)
if err != nil {
return fmt.Errorf("failed to subscribe to events: %w", err)
}
// Mint a per-call RunID so we can correlate the terminal
// RunComplete with *this* SendMessage even if the session was
// busy and another turn finished first. Without it the stream
// loop would exit on whichever RunComplete arrived first for
// the same session and drop the queued prompt's output.
runID := uuid.New().String()
if err := c.SendMessage(ctx, ws.ID, sess.ID, runID, prompt); err != nil {
return fmt.Errorf("failed to send message: %w", err)
}
stream := &runStream{
sessionID: sess.ID,
runID: runID,
out: os.Stdout,
read: make(map[string]int),
}
// Start herdr integration when running inside a herdr pane.
hc := herdr.Init()
hc.SetSessionID(sess.ID)
defer hc.Close()
defer func() {
if progress && stderrTTY {
_, _ = fmt.Fprintf(os.Stderr, ansi.ResetProgressBar)
}View on GitHub (pinned to 7944b8e522)
Solutions
- Verify the agent is ready (the run already waits via waitForAgent) and re-run
- Test provider credentials with `crush` interactive mode
- Start a fresh session (drop --continue) if the old session state is suspect
- Inspect verbose logs for the wrapped SendMessage cause
Example fix
// before: empty prompt when arg parsing failed
prompt := flag.Arg(0) // ""
c.SendMessage(ctx, ws.ID, sess.ID, runID, prompt)
// after
if prompt == "" {
return fmt.Errorf("prompt is required")
}
if err := c.SendMessage(ctx, ws.ID, sess.ID, runID, prompt); err != nil {
return fmt.Errorf("failed to send message: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(prompt) == "" {
return fmt.Errorf("prompt is required")
}
if sess == nil || sess.ID == "" {
return fmt.Errorf("no active session; cannot send message")
} Try / catch
if err := c.SendMessage(ctx, ws.ID, sess.ID, runID, prompt); err != nil {
if errors.Is(err, context.Canceled) {
return err
}
return fmt.Errorf("failed to send message: %w", err)
} Prevention
- Always validate the prompt is non-empty before sending
- Ensure waitForAgent succeeded before SendMessage
- Use a fresh runID (uuid) for every SendMessage as the code does
- Recreate the session if SendMessage fails repeatedly (state may be corrupt)
When it happens
Trigger: `crush run` calls c.SendMessage(ctx, ws.ID, sess.ID, runID, prompt) and it returns an error — agent for the session isn't running, session state is invalid, or provider call setup fails immediately.
Common situations: Session was resolved but its agent was torn down; empty prompt; provider credentials rejected at request time; the session is in a corrupted state after a crashed run.
Related errors
- agent configuration not found
- agent coordinator not initialized
- failed to initialize coder agent: %w
- cannot continue an agent tool session: %s
- failed to disable docker MCP: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/628b6e508cf33aba.
Report an issue: GitHub.