chenhg5/cc-connect · error

only WAV format can be compressed, got: %s

Error message

only WAV format can be compressed, got: %s

What it means

compressAudio only supports converting WAV input (to MP3 via ffmpeg) to fit DingTalk's media size limits; any other input format is rejected with this error before ffmpeg is invoked. The library deliberately restricts compression to WAV because that is what the agent's TTS pipeline emits and what ffmpeg can reliably transcode here.

Source

Thrown at platform/dingtalk/dingtalk.go:1301

	defer func() { _ = resp.Body.Close() }()

	respBody, _ := io.ReadAll(resp.Body)
	slog.Debug("dingtalk: oToMessages API response", "status", resp.StatusCode, "body", string(respBody))

	if resp.StatusCode != 200 {
		return fmt.Errorf("dingtalk: send audio failed: status=%d, body=%s", resp.StatusCode, string(respBody))
	}

	slog.Info("dingtalk: voice message sent successfully", "media_id", mediaID, "conversation_id", rc.conversationId)
	return nil
}

// compressAudio compresses audio if it exceeds size limits.
// Uses ffmpeg to convert WAV to MP3 format (DingTalk supported, ~10:1 compression ratio).
func (p *Platform) compressAudio(ctx context.Context, audio []byte, format string) ([]byte, string, error) {
	// Only WAV format can be compressed to MP3
	if strings.ToLower(format) != "wav" {
		return nil, "", fmt.Errorf("only WAV format can be compressed, got: %s", format)
	}

	return p.compressAudioWithFFmpeg(ctx, audio, format)
}

// compressAudioWithFFmpeg compresses audio using ffmpeg with stdin/stdout pipes.
// Converts WAV to MP3 format (64 kbps for voice).
func (p *Platform) compressAudioWithFFmpeg(ctx context.Context, audio []byte, format string) ([]byte, string, error) {
	ffmpegPath, err := exec.LookPath("ffmpeg")
	if err != nil {
		return nil, "", fmt.Errorf("ffmpeg not found: %w", err)
	}

	args := []string{
		"-i", "pipe:0",
		"-ar", "16000", // 16kHz sample rate for voice
		"-ac", "1", // mono
		"-b:a", "64k", // 64 kbps bitrate (voice quality)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Convert/transcode the audio to WAV before handing it to sendAudio/compressAudio.
  2. Fix the format string passed in — it must be exactly "wav" (case is normalized, but not MIME types or extensions).
  3. If the audio is already MP3 and small enough, skip compression and upload directly instead of routing through compressAudio.

Example fix

// before
return p.compressAudio(ctx, audio, "audio/wav")
// after
return p.compressAudio(ctx, audio, "wav")
Defensive patterns

Strategy: validation

Validate before calling

func canCompress(format string) bool { return strings.ToLower(strings.TrimPrefix(format, ".")) == "wav" }
if !canCompress(format) && len(audio) > maxSize { return fmt.Errorf("cannot compress %s; convert to WAV first", format) }

Prevention

When it happens

Trigger: Calling compressAudio (or the send-voice path that auto-compresses) with format set to anything other than "wav" (case-insensitive check), e.g. "mp3", "ogg", "amr".

Common situations: An upstream agent produced non-WAV TTS output; a format string like ".wav" or "audio/wav" was passed instead of the bare "wav"; config switched TTS output format without updating the DingTalk path.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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