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 nil

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Inspect the wrapped error for the Bot API description string and act on it directly.
  2. Ensure the audio bytes are OGG with Opus codec — this is the only format sendVoice accepts reliably.
  3. Verify bot membership/send permission in the target chat.
  4. 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

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.