chenhg5/cc-connect · error
%s: convert to opus: %w
Error message
%s: convert to opus: %w
What it means
Before sending a voice message, SendAudio must convert non-opus audio to Feishu's required opus format using core.ConvertAudioToOpus (which shells out to ffmpeg). This error wraps a conversion failure. It means ffmpeg is missing, the input bytes are not valid audio in the claimed format, or the conversion process failed/timed out.
Source
Thrown at platform/feishu/feishu.go:5473
}
return nil
})
})
}
// SendAudio uploads audio bytes to Feishu and sends a voice message.
// Implements core.AudioSender interface.
// Feishu audio messages require opus format; non-opus input is converted via ffmpeg.
func (p *Platform) SendAudio(ctx context.Context, rctx any, audio []byte, format string) error {
rc, ok := rctx.(replyContext)
if !ok {
return fmt.Errorf("%s: SendAudio: invalid reply context type %T", p.tag(), rctx)
}
if format != "opus" {
converted, err := core.ConvertAudioToOpus(ctx, audio, format)
if err != nil {
return fmt.Errorf("%s: convert to opus: %w", p.tag(), err)
}
audio = converted
format = "opus"
}
var uploadResp *larkim.CreateFileResp
if err := p.withTransientRetry(ctx, "upload audio", func() error {
return p.withFreshTenantAccessTokenRetry(ctx, "upload audio", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {
req := larkim.NewCreateFileReqBuilder().
Body(larkim.NewCreateFileReqBodyBuilder().
FileType(larkim.FileTypeOpus).
FileName("tts_audio.opus").
File(bytes.NewReader(audio)).
Build()).
Build()
var err error
uploadResp, err = client.Im.File.Create(ctx, req, options...)
if err != nil {View on GitHub (pinned to 4000b2338a)
Solutions
- Install ffmpeg and confirm it is on PATH (ffmpeg -version)
- Check the input audio is valid and matches the declared format
- Send audio already encoded as opus to skip conversion
- Wrap the cause (%w) to see ffmpeg's stderr for the exact failure
Example fix
// before
err := p.SendAudio(ctx, rc, ttsOutput, "mp3")
// after
opus, err := core.ConvertAudioToOpus(ctx, ttsOutput, "mp3") // surface the ffmpeg error early
if err != nil { slog.Error("audio conversion failed", "err", err) } else { p.SendAudio(ctx, rc, opus, "opus") } Defensive patterns
Strategy: fallback
Validate before calling
// check ffmpeg availability at startup
if _, err := exec.LookPath("ffmpeg"); err != nil { slog.Warn("ffmpeg not found; audio conversion will fail") } Try / catch
converted, err := core.ConvertAudioToOpus(ctx, audio, format)
if err != nil {
slog.Error("opus conversion failed", "err", err)
return fallbackSendAsFile(ctx, audio, format) // degrade gracefully
} Prevention
- Install ffmpeg in the deployment image (verify with ffmpeg -version)
- Validate audio bytes are non-empty before sending
- Prefer opus input to skip conversion
- Check ffmpeg stderr in the wrapped error
When it happens
Trigger: format != "opus" and ConvertAudioToOpus returns an error: ffmpeg binary not on PATH, corrupt/empty audio bytes, unsupported input container/codec, or the conversion command exits non-zero.
Common situations: Docker images without ffmpeg installed; agents returning webm/ogg streams mislabeled as mp3/wav; zero-length audio from a TTS tool; ffmpeg version too old for the requested flags.
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
- dingtalk: convert MP3 to AMR failed: %w
- ffmpeg not found in PATH: install ffmpeg to enable voice mes
- ffmpeg conversion failed: %w (stderr: %s)
- ffmpeg not found in PATH: install ffmpeg to enable audio con
- ffmpeg opus conversion failed: %w (stderr: %s)
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/eb3b7ecde3b21ece.
Report an issue: GitHub.