chenhg5/cc-connect · error
%s: SendAudio: invalid reply context type %T
Error message
%s: SendAudio: invalid reply context type %T
What it means
SendAudio implements the core.AudioSender interface and expects the reply-context parameter rctx to be the platform-internal replyContext type. This error is thrown when the type assertion rctx.(replyContext) fails, i.e. the caller passed a reply context produced by a different platform or an unexpected value. Like error 1230, it indicates a caller/platform contract violation rather than a runtime condition.
Source
Thrown at platform/feishu/feishu.go:5467
resp, err := client.Im.Message.Delete(ctx, req, options...)
if err != nil {
return fmt.Errorf("%s: delete preview message: %w", p.tag(), err)
}
if !resp.Success() {
return fmt.Errorf("%s: delete preview message code=%d msg=%s", p.tag(), resp.Code, resp.Msg)
}
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").View on GitHub (pinned to 4000b2338a)
Solutions
- Pass the reply context exactly as obtained from this platform's incoming-message/reply API
- Verify only one version of the feishu platform package is linked (go version -m)
- Do not fabricate reply contexts; route audio through the engine's reply pipeline
- If you must hold contexts generically, key them by platform name
Example fix
// before
feishuPlatform.SendAudio(ctx, genericReplyCtx, audio, "mp3")
// after
if rc, ok := genericReplyCtx.(feishu.ReplyContext); ok {
feishuPlatform.SendAudio(ctx, rc, audio, "mp3")
} Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := rctx.(feishu.ReplyContext); !ok { return fmt.Errorf("SendAudio requires a feishu reply context, got %T", rctx) } Type guard
func asFeishuReplyContext(v any) (feishu.ReplyContext, bool) { rc, ok := v.(feishu.ReplyContext); return rc, ok } Prevention
- Always pass the reply context straight from the incoming message handler
- Verify single feishu package version in the binary
- Never fabricate reply contexts; use the engine reply pipeline
When it happens
Trigger: Calling SendAudio with an rctx from another platform adapter, a raw chat/message ID, a nil interface, or a handle from a differently-built feishu package (duplicate module versions).
Common situations: Engine/plugin code that caches reply contexts across platforms; a custom agent sending audio through the wrong platform instance; mixing two versions of the feishu package in one binary (vendored vs module).
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- %s: SendVideo: invalid reply context type %T
- bridge: invalid reply context type %T
- %s: invalid reply context type %T
- %s: SendFile: invalid reply context type %T
- %s: StreamRichCardText: invalid preview handle type %T
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/e2d9390086854ce6.
Report an issue: GitHub.