chenhg5/cc-connect · error
send audio: %w
Error message
send audio: %w
What it means
cc-connect wraps failures from the platform adapter's SendAudio call (delivering synthesized TTS audio to the messaging platform) with the 'send audio: %w' prefix. The TTS synthesis itself succeeded; the failure occurs while transmitting the audio bytes to the platform (e.g. Feishu, Telegram). The platform-specific cause is preserved via %w.
Source
Thrown at core/engine.go:15893
return fmt.Errorf("text exceeds max_text_len (%d > %d)", utf8.RuneCountInString(text), e.tts.MaxTextLen)
}
as, ok := p.(AudioSender)
if !ok {
return fmt.Errorf("platform %s does not support audio sending", p.Name())
}
slog.Info("tts: starting synthesis", "voice", e.tts.Voice, "speed", e.tts.Speed, "text_len", len(text))
opts := TTSSynthesisOpts{
Voice: e.tts.Voice,
LanguageType: e.tts.LanguageType,
Speed: e.tts.Speed,
}
audioData, format, err := e.tts.TTS.Synthesize(e.ctx, StripMarkdown(text), opts)
if err != nil {
return fmt.Errorf("synthesize: %w", err)
}
slog.Info("tts: synthesis successful", "format", format, "audio_size", len(audioData))
if err := as.SendAudio(e.ctx, replyCtx, audioData, format); err != nil {
return fmt.Errorf("send audio: %w", err)
}
slog.Info("tts: audio sent successfully", "platform", p.Name())
return nil
}
// ──────────────────────────────────────────────────────────────
// Bot-to-bot relay
// ──────────────────────────────────────────────────────────────
type platformNameOnly struct {
name string
}
func (p platformNameOnly) Name() string { return p.name }
func (platformNameOnly) Start(MessageHandler) error { return nil }
func (platformNameOnly) Reply(context.Context, any, string) error { return nil }
func (platformNameOnly) Send(context.Context, any, string) error { return nil }
func (platformNameOnly) Stop() error { return nil }View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped cause for the platform-specific failure (auth vs size vs format)
- Re-authenticate or refresh the platform bot token in config.toml
- Check the platform's max audio/file size and the produced audio_size in the preceding log line
- Convert the TTS output to a format the platform accepts (e.g. opus/ogg for Telegram voice)
- Retry — upload failures are often transient
Example fix
// before
if err := as.SendAudio(e.ctx, replyCtx, audioData, format); err != nil {
return fmt.Errorf("send audio: %w", err)
}
// after
if err := as.SendAudio(e.ctx, replyCtx, audioData, format); err != nil {
slog.Warn("tts: audio send failed, falling back to text", "platform", p.Name(), "error", err)
if ferr := e.replyText(replyCtx, text); ferr != nil {
return fmt.Errorf("send audio: %w (text fallback also failed: %v)", err, ferr)
}
return nil
} Defensive patterns
Strategy: fallback
Validate before calling
// check platform capability before attempting audio
if _, ok := as.(interface{ SendAudio(ctx context.Context, rc ReplyContext, data []byte, format string) error }); !ok {
return e.replyText(replyCtx, text)
} Try / catch
if err := as.SendAudio(e.ctx, replyCtx, audioData, format); err != nil {
slog.Warn("send audio failed; falling back to text", "platform", p.Name(), "error", err)
return e.replyText(replyCtx, text)
} Prevention
- Confirm the target platform supports audio and its size/format limits before enabling TTS
- Keep platform bot tokens refreshed and validated at startup
- Cap TTS audio length to stay under the smallest platform limit
- Implement text fallback so users always get a reply
When it happens
Trigger: After successful Synthesize, as.SendAudio(e.ctx, replyCtx, audioData, format) returns an error — the platform API rejects the upload (auth token expired, file too large, unsupported audio format for that platform, network failure, or the chat/message target is invalid).
Common situations: Platform bot token expired or rotated; audio file exceeds the platform's upload size limit; audio format from TTS (e.g. mp3) not accepted by the platform; chat ID no longer valid (user blocked bot); transient network failure during upload.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- synthesize: %w
- openai tts: create request: %w
- openai tts: request: %w
- openai tts API %d: %s
- openai tts: read audio: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/d7e60595a6b624e4.
Report an issue: GitHub.