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

  1. Verify the agent is ready (the run already waits via waitForAgent) and re-run
  2. Test provider credentials with `crush` interactive mode
  3. Start a fresh session (drop --continue) if the old session state is suspect
  4. 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

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


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