chenhg5/cc-connect · error

sendVoice failed: %w

Error message

sendVoice failed: %w

What it means

This error is wrapped inside the combined error returned when the Telegram platform tries to send a voice note via SendVoice and it fails, then falls back to SendAudio, which also fails. The platform joins both underlying errors with errors.Join under a 'telegram: SendAudio:' prefix so the caller can see the full failure chain. It means the Bot API sendVoice call itself rejected or could not deliver the audio payload.

Source

Thrown at platform/telegram/telegram.go:1217

		// Attempt these formats directly with sendVoice first.
	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,

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the joined fallbackErr (sendAudio fallback failed) for the Bot API description — it usually names the real cause (e.g. 'wrong file identifier/HTTP URL specified').
  2. Verify the audio is a valid OGG encoded with OPUS codec for sendVoice; re-encode with ffmpeg -c:a libopus if not.
  3. Confirm the bot is a member of the target chat with permission to send messages.
  4. Retry on transient network errors; reduce file size below 50 MB if applicable.

Example fix

// before: single attempt, opaque failure
err := p.sendVoice(ctx, rc, data, format)
// after: inspect joined errors to find root cause
var joined interface{ Unwrap() []error }
if errors.As(err, &joined) { for _, e := range joined { log.Println(e) } }
Defensive patterns

Strategy: fallback

Validate before calling

if len(audio) > 50*1024*1024 { return errors.New("file exceeds 50 MB bot upload limit") }

Try / catch

if err := p.sendVoice(ctx, rc, data, format); err != nil {
    if fbErr := p.sendAudio(ctx, rc, data, format); fbErr != nil {
        return errors.Join(err, fbErr) // inspect both for root cause
    }
}

Prevention

When it happens

Trigger: p.sendVoice(ctx, rc, audioData, sendFormat) returns an error (Bot API error, network failure, bad format/fileID) AND the p.sendAudio fallback also errors; both are joined and returned from the voice-sending path of the audio-sending method.

Common situations: Sending OGG/OPUS voice notes with an unsupported container that Telegram rejects; network interruption to api.telegram.org; bot lacking permission to post in the chat; file exceeding Telegram's 50 MB bot upload limit.

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/47bb3e56a8863329. Report an issue: GitHub.