{"record":{"id":"21bcc1fd8705c286","repo":"chenhg5/cc-connect","slug":"dingtalk-convert-mp3-to-amr-failed-w","errorCode":null,"errorMessage":"dingtalk: convert MP3 to AMR failed: %w","messagePattern":"dingtalk: convert MP3 to AMR failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":1194,"sourceCode":"// DingTalk voice messages only support ogg/amr formats (not mp3).\nfunc (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(\"dingtalk: SendAudio: invalid reply context type %T\", rctx)\n\t}\n\n\tslog.Debug(\"dingtalk: SendAudio called\", \"format\", format, \"size\", len(audio), \"conversation_id\", rc.conversationId)\n\n\t// Convert MP3 to OGG if needed (DingTalk voice messages only support ogg/amr)\n\tif strings.ToLower(format) == \"mp3\" {\n\t\tslog.Debug(\"dingtalk: converting MP3 to OGG format (DingTalk requirement)\")\n\t\toggAudio, err := core.ConvertMP3ToOGG(ctx, audio)\n\t\tif err != nil {\n\t\t\tslog.Warn(\"dingtalk: MP3 to OGG conversion failed\", \"error\", err)\n\t\t\t// Fallback: try AMR format instead\n\t\t\tamrAudio, err := core.ConvertMP3ToAMR(ctx, audio)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"dingtalk: convert MP3 to AMR failed: %w\", err)\n\t\t\t}\n\t\t\taudio = amrAudio\n\t\t\tformat = \"amr\"\n\t\t} else {\n\t\t\taudio = oggAudio\n\t\t\tformat = \"ogg\"\n\t\t}\n\t\tslog.Debug(\"dingtalk: audio converted\", \"new_format\", format, \"new_size\", len(audio))\n\t}\n\n\t// Compress audio if too large (DingTalk limit is 2MB)\n\tconst maxAudioSize = 2 * 1024 * 1024\n\tif len(audio) > maxAudioSize {\n\t\tslog.Debug(\"dingtalk: audio too large, compressing\", \"size\", len(audio), \"max\", maxAudioSize)\n\t\tcompressed, compressedFormat, err := p.compressAudio(ctx, audio, format)\n\t\tif err != nil {\n\t\t\tslog.Warn(\"dingtalk: compression failed, using original\", \"error\", err)\n\t\t} else {","sourceCodeStart":1176,"sourceCodeEnd":1212,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L1176-L1212","documentation":"When the incoming audio is MP3, SendAudio first tries converting it to OGG (DingTalk voice requirement); if that fails it falls back to AMR conversion, and if that also fails this error wraps the AMR failure. DingTalk voice messages only support ogg/amr, so without a successful conversion the audio cannot be sent.","triggerScenarios":"Sending an MP3 audio message where core.ConvertMP3ToOGG fails (e.g. ffmpeg not installed) and the fallback core.ConvertMP3ToAMR also fails (ffmpeg missing, malformed/corrupt MP3 input, or unsupported sample rate/bitrate).","commonSituations":"ffmpeg (or the converter binary) not installed on the host, corrupted or zero-byte audio from the agent, unusual MP3 encodings the converter can't handle.","solutions":["Verify the conversion tool (ffmpeg) is installed and on PATH: ffmpeg -version","Validate the input audio is a non-empty, well-formed MP3","Pre-convert audio to OGG or AMR before calling SendAudio to skip conversion","Check the wrapped error for the converter's specific complaint"],"exampleFix":"// before\namrAudio, err := core.ConvertMP3ToAMR(ctx, audio)\nif err != nil { return fmt.Errorf(\"dingtalk: convert MP3 to AMR failed: %w\", err) }\n// after (pre-validate)\nif len(audio) == 0 { return errors.New(\"dingtalk: empty audio payload\") }\nif _, err := exec.LookPath(\"ffmpeg\"); err != nil { return fmt.Errorf(\"dingtalk: ffmpeg required for audio conversion: %w\", err) }","handlingStrategy":"fallback","validationCode":"if len(audio) == 0 { return errors.New(\"empty audio\") }\nif _, err := exec.LookPath(\"ffmpeg\"); err != nil { return errors.New(\"ffmpeg not installed; cannot convert MP3 for DingTalk\") }","typeGuard":null,"tryCatchPattern":"if err := p.SendAudio(ctx, rc, mp3Data, \"mp3\"); err != nil && strings.Contains(err.Error(), \"convert MP3\") {\n    // supply pre-converted OGG instead\n    err = p.SendAudio(ctx, rc, oggData, \"ogg\")\n}","preventionTips":["Install ffmpeg on hosts running cc-connect and verify it at startup (doctor check)","Prefer sending OGG/AMR audio natively to skip conversion entirely","Validate audio payloads are non-empty and well-formed before sending","Check audio sample rates are within ffmpeg-supported ranges"],"tags":["dingtalk","audio","conversion","ffmpeg"],"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-14T00:17:10.932Z"}