chenhg5/cc-connect · error
telegram: SendAudio: sendVoice: %w
Error message
telegram: SendAudio: sendVoice: %w
What it means
Returned when p.sendVoice fails and there is no audio fallback path taken (the fallback only runs when sendFormat/sendData support it). It wraps the raw sendVoice error under the 'telegram: SendAudio: sendVoice:' prefix, so the failure is entirely in the Bot API sendVoice call.
Source
Thrown at platform/telegram/telegram.go:1223
sendData = converted
sendFormat = "opus"
}
if err := p.sendVoice(ctx, rc, sendData, sendFormat); err != nil {
if sendFormat == "mp3" || sendFormat == "m4a" {
if fallbackErr := p.sendAudio(ctx, rc, sendData, sendFormat); fallbackErr == nil {
return nil
} else {
return fmt.Errorf(
"telegram: SendAudio: %w",
errors.Join(
fmt.Errorf("sendVoice failed: %w", err),
fmt.Errorf("sendAudio fallback failed: %w", fallbackErr),
),
)
}
}
return fmt.Errorf("telegram: SendAudio: sendVoice: %w", err)
}
return nil
}
func (p *Platform) sendVoice(ctx context.Context, rc replyContext, audio []byte, format string) error {
bot, err := p.connectedBot("send voice")
if err != nil {
return err
}
params := &tgbot.SendVoiceParams{
ChatID: rc.chatID,
MessageThreadID: rc.threadID,
Voice: &models.InputFileUpload{Filename: "tts_audio." + telegramAudioFileExt(format), Data: bytes.NewReader(audio)},
}
if _, err := bot.SendVoice(ctx, params); err != nil {
return err
}
return nilView on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped error for the Bot API description string and act on it directly.
- Ensure the audio bytes are OGG with Opus codec — this is the only format sendVoice accepts reliably.
- Verify bot membership/send permission in the target chat.
- Add retry with backoff for 5xx/network errors; surface 429 retry_after to the caller.
Example fix
// before
return fmt.Errorf("telegram: SendAudio: sendVoice: %w", err)
// after: detect retryable Bot API errors
var apiErr *tgbot.Error
if errors.As(err, &apiErr) && apiErr.RetryAfter > 0 { time.Sleep(...) } Defensive patterns
Strategy: retry
Validate before calling
if !strings.HasSuffix(strings.ToLower(filename), ".ogg") { /* convert to ogg/opus first */ } Try / catch
err := p.sendVoice(ctx, rc, data, format)
if err != nil {
if isTransient(err) { return retryWithBackoff(send) }
return fmt.Errorf("telegram: SendAudio: sendVoice: %w", err)
} Prevention
- Only send OGG/Opus via sendVoice
- Handle Bot API 429/5xx with retries
- Verify file_ids are still valid before reuse
- Surface the wrapped Bot API description to logs
When it happens
Trigger: The audio-sending method calls p.sendVoice, which returns err (Bot API error, connection failure, invalid parameters), and the code path skips the sendAudio fallback, returning fmt.Errorf("telegram: SendAudio: sendVoice: %w", err).
Common situations: Voice payload not OGG/Opus ('Unsupported content type'); file_id referencing a deleted file; chat_write_denied in groups; network timeout to Telegram servers.
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
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/f90b23e336e1b292.
Report an issue: GitHub.