chenhg5/cc-connect · error

weixin: convert %s to AMR: %w

Error message

weixin: convert %s to AMR: %w

What it means

SendAudio in the weixin platform wraps the AMR conversion failure. WeChat (weixin) only accepts AMR audio, so any TTS-produced audio in another format (default WAV) is first run through core.ConvertAudioToAMR; if the underlying ffmpeg conversion fails, the error is wrapped and returned with the source format named.

Source

Thrown at platform/weixin/media_outbound.go:266

func (p *Platform) SendAudio(ctx context.Context, replyCtx any, audio []byte, format string) error {
	rc, err := p.resolveReplyContext(replyCtx)
	if err != nil {
		return err
	}
	if len(audio) == 0 {
		return fmt.Errorf("weixin: empty audio")
	}

	// Convert to AMR format if not already AMR
	sendData := audio
	sendFormat := strings.ToLower(strings.TrimSpace(format))
	if sendFormat == "" {
		sendFormat = "wav" // TTS typically outputs WAV
	}
	if sendFormat != "amr" {
		converted, err := core.ConvertAudioToAMR(ctx, audio, sendFormat)
		if err != nil {
			return fmt.Errorf("weixin: convert %s to AMR: %w", sendFormat, err)
		}
		sendData = converted
		sendFormat = "amr"
	}

	slog.Debug("weixin: audio converted", "format", sendFormat, "size", len(sendData))

	// Upload to CDN as file type (voice uses same CDN upload mechanism)
	ref, err := p.uploadToWeixinCDN(ctx, rc.peerUserID, sendData, uploadMediaFile, "SendAudio")
	if err != nil {
		return err
	}

	// Send as voice message
	item := messageItem{
		Type: messageItemVoice,
		VoiceItem: &voiceItem{
			Media: &cdnMedia{

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Install ffmpeg with AMR encoder support (libopencore-amrnb) on the host
  2. Verify the incoming audio bytes actually match sendFormat (play/ffprobe the file)
  3. Check the wrapped inner error for the exact ffmpeg failure reason
  4. If the source is already AMR, ensure sendFormat is set to "amr" so conversion is skipped

Example fix

// before
converted, err := core.ConvertAudioToAMR(ctx, audio, sendFormat)
if err != nil {
    return fmt.Errorf("weixin: convert %s to AMR: %w", sendFormat, err)
}
// after
if len(audio) == 0 {
    return fmt.Errorf("weixin: empty %s audio before AMR conversion", sendFormat)
}
converted, err := core.ConvertAudioToAMR(ctx, audio, sendFormat)
if err != nil {
    return fmt.Errorf("weixin: convert %s to AMR: %w", sendFormat, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := exec.LookPath("ffmpeg"); err != nil {
    return fmt.Errorf("ffmpeg required for AMR conversion")
}
if len(audio) == 0 {
    return fmt.Errorf("empty audio payload")
}

Try / catch

converted, err := platform.SendAudio(ctx, audio, format)
if err != nil && strings.Contains(err.Error(), "convert") {
    log.Warn("AMR conversion failed; notify user audio undeliverable", "err", err)
}

Prevention

When it happens

Trigger: SendAudio is called with audio data whose format is not AMR and core.ConvertAudioToAMR fails — typically because ffmpeg is not installed, the input bytes are not valid WAV/MP3 audio, or the conversion subprocess errors/times out.

Common situations: Deployed container/host lacks ffmpeg; a text-to-speech backend returned an empty or truncated payload; the audio is declared as one format but actually contains different bytes; AMR encoder not available in the ffmpeg build.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/921c01038ef96fa8. Report an issue: GitHub.