{"record":{"id":"39f203f1a8433f6c","repo":"chenhg5/cc-connect","slug":"telegram-sendaudio-convert-s-to-opus-w","errorCode":null,"errorMessage":"telegram: SendAudio: convert %s to opus: %w","messagePattern":"telegram: SendAudio: convert (.+?) to opus: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/telegram/telegram.go","lineNumber":1203,"sourceCode":"func (p *Platform) SendAudio(ctx context.Context, rctx any, audio []byte, format string) error {\n\trc, ok := rctx.(replyContext)\n\tif !ok {\n\t\treturn fmt.Errorf(\"telegram: SendAudio: invalid reply context type %T\", rctx)\n\t}\n\n\tsendData := audio\n\tsendFormat := strings.ToLower(strings.TrimSpace(format))\n\tif sendFormat == \"\" {\n\t\tsendFormat = \"ogg\"\n\t}\n\n\tswitch sendFormat {\n\tcase \"ogg\", \"opus\", \"mp3\", \"m4a\":\n\t\t// Attempt these formats directly with sendVoice first.\n\tdefault:\n\t\tconverted, err := telegramConvertAudioToOpus(ctx, audio, sendFormat)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"telegram: SendAudio: convert %s to opus: %w\", sendFormat, err)\n\t\t}\n\t\tsendData = converted\n\t\tsendFormat = \"opus\"\n\t}\n\n\tif err := p.sendVoice(ctx, rc, sendData, sendFormat); err != nil {\n\t\tif sendFormat == \"mp3\" || sendFormat == \"m4a\" {\n\t\t\tif fallbackErr := p.sendAudio(ctx, rc, sendData, sendFormat); fallbackErr == nil {\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"telegram: SendAudio: %w\",\n\t\t\t\t\terrors.Join(\n\t\t\t\t\t\tfmt.Errorf(\"sendVoice failed: %w\", err),\n\t\t\t\t\t\tfmt.Errorf(\"sendAudio fallback failed: %w\", fallbackErr),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}","sourceCodeStart":1185,"sourceCodeEnd":1221,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/telegram/telegram.go#L1185-L1221","documentation":"SendAudio wraps failures from telegramConvertAudioToOpus with \"telegram: SendAudio: convert %s to opus: \". This path runs only for formats other than ogg/opus/mp3/m4a (e.g. wav, flac): the audio must be transcoded to Opus/OGG for Telegram voice messages and the ffmpeg conversion failed.","triggerScenarios":"Calling SendAudio with a format outside {ogg,opus,mp3,m4a} when ffmpeg is missing from PATH, exits non-zero, or the input bytes are corrupt/unsupported.","commonSituations":"Deploying in a slim container without ffmpeg installed; passing format strings like \"wav\" or \"PCM\"; truncated/corrupt audio buffers from the synthesizer; ffmpeg version lacking the libopus encoder.","solutions":["Install ffmpeg (apt-get install ffmpeg / apk add ffmpeg) and verify it is on PATH","Convert common formats (mp3/m4a) which skip conversion and use sendVoice directly, with sendAudio fallback","Normalize input to wav/ogg at the synthesis step before calling SendAudio","Validate the audio bytes are non-empty and correctly encoded","Run the same ffmpeg command manually to see the raw codec error"],"exampleFix":"// before\np.SendAudio(ctx, rc, wavBytes, \"wav\") // requires ffmpeg\n// after\n// guard before calling\nif _, err := exec.LookPath(\"ffmpeg\"); err != nil {\n    return fmt.Errorf(\"audio conversion unavailable: install ffmpeg: %w\", err)\n}\np.SendAudio(ctx, rc, wavBytes, \"wav\")","handlingStrategy":"fallback","validationCode":"// guard conversion dependencies before calling\nif _, err := exec.LookPath(\"ffmpeg\"); err != nil {\n    return fmt.Errorf(\"ffmpeg required for %s audio: %w\", format, err)\n}","typeGuard":"func needsOpusConversion(format string) bool {\n    switch strings.ToLower(strings.TrimSpace(format)) {\n    case \"\", \"ogg\", \"opus\", \"mp3\", \"m4a\":\n        return false\n    }\n    return true\n}","tryCatchPattern":"if err := p.SendAudio(ctx, rc, audio, \"wav\"); err != nil {\n    if strings.Contains(err.Error(), \"convert\") {\n        // fall back to mp3 or install ffmpeg\n    }\n    return err\n}","preventionTips":["Install ffmpeg in the deployment image","Emit TTS output as ogg/opus/mp3/m4a to skip conversion","Validate audio bytes are non-empty and well-formed","Test the conversion path in CI with ffmpeg present"],"tags":["telegram","audio","ffmpeg","transcode"],"backgroundTag":"missing-optional-dependency","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}