chenhg5/cc-connect · error
sendAudio fallback failed: %w
Error message
sendAudio fallback failed: %w
What it means
This is the fallback half of the joined error returned when both SendVoice and the SendAudio fallback fail while sending a voice/audio message. It wraps the error from p.sendAudio, the fallback path used when voice sending is unsupported or fails. Its presence means Telegram also rejected the audio variant of the message.
Source
Thrown at platform/telegram/telegram.go:1218
default:
converted, err := telegramConvertAudioToOpus(ctx, audio, sendFormat)
if err != nil {
return fmt.Errorf("telegram: SendAudio: convert %s to opus: %w", sendFormat, err)
}
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)},View on GitHub (pinned to 4000b2338a)
Solutions
- Read the wrapped fallbackErr text for the Bot API's specific rejection reason.
- Convert the audio to a standard MP3/M4A and resend via sendAudio, or OGG/Opus for voice.
- Handle HTTP 429 retry_after from the Bot API by waiting and retrying.
- Check bot chat permissions and file size (50 MB bot limit).
Example fix
// before: ignoring which leg failed
return err
// after: branch on the joined causes
if strings.Contains(err.Error(), "sendAudio fallback failed") { /* audio-specific handling */ } Defensive patterns
Strategy: try-catch
Validate before calling
if len(audio) == 0 { return errors.New("empty audio payload") } Try / catch
if err := send(); err != nil {
var apiErr *tgbot.Error
if errors.As(err, &apiErr) && apiErr.Code == 429 {
time.Sleep(time.Duration(apiErr.RetryAfter) * time.Second)
}
} Prevention
- Validate audio codec/container before upload
- Handle 429 retry_after responses
- Confirm bot membership in target chats
- Log joined errors separately for diagnosis
When it happens
Trigger: After sendVoice fails, p.sendAudio(ctx, rc, sendData, sendFormat) is invoked and returns a non-nil error; the code then returns fmt.Errorf("telegram: SendAudio: %w", errors.Join(voiceErr, audioFallbackErr)).
Common situations: Audio file in a codec/container Telegram's sendAudio rejects (e.g. malformed MP3); caption or duration fields out of range; expired or wrong file_id; bot rate-limited (429).
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
- sendVoice failed: %w
- telegram: SendAudio: %w
- telegram: SendAudio: sendVoice: %w
- telegram: sendWithButtons: %w
- get file: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/cd0b58cf65a9352f.
Report an issue: GitHub.