{"record":{"id":"ed3fe063d133e87c","repo":"chenhg5/cc-connect","slug":"s-sendfile-invalid-reply-context-type-t","errorCode":null,"errorMessage":"%s: SendFile: invalid reply context type %T","messagePattern":"(.+?): SendFile: invalid reply context type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/feishu.go","lineNumber":3314,"sourceCode":"\t\t\tif !uploadResp.Success() {\n\t\t\t\treturn fmt.Errorf(\"%s: upload image code=%d msg=%s\", p.tag(), uploadResp.Code, uploadResp.Msg)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t}); err != nil {\n\t\treturn \"\", err\n\t}\n\tif uploadResp.Data == nil || uploadResp.Data.ImageKey == nil {\n\t\treturn \"\", fmt.Errorf(\"%s: upload image: no image_key returned\", p.tag())\n\t}\n\n\treturn *uploadResp.Data.ImageKey, nil\n}\n\nfunc (p *Platform) SendFile(ctx context.Context, rctx any, file core.FileAttachment) error {\n\trc, ok := rctx.(replyContext)\n\tif !ok {\n\t\treturn fmt.Errorf(\"%s: SendFile: invalid reply context type %T\", p.tag(), rctx)\n\t}\n\n\tfileName := file.FileName\n\tif fileName == \"\" {\n\t\tfileName = \"attachment\"\n\t}\n\tfileType := detectFeishuFileType(file.MimeType, fileName)\n\tvar uploadResp *larkim.CreateFileResp\n\tif err := p.withTransientRetry(ctx, \"upload file\", func() error {\n\t\treturn p.withFreshTenantAccessTokenRetry(ctx, \"upload file\", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {\n\t\t\treq := larkim.NewCreateFileReqBuilder().\n\t\t\t\tBody(larkim.NewCreateFileReqBodyBuilder().\n\t\t\t\t\tFileType(fileType).\n\t\t\t\t\tFileName(fileName).\n\t\t\t\t\tFile(bytes.NewReader(file.Data)).\n\t\t\t\t\tBuild()).\n\t\t\t\tBuild()\n\t\t\tvar err error","sourceCodeStart":3296,"sourceCodeEnd":3332,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L3296-L3332","documentation":"SendFile type-asserts its rctx parameter to the platform-internal replyContext type; the assertion failed, meaning the caller passed a reply context from a different platform or a non-context value. This is an internal programming/contract error, not an API failure.","triggerScenarios":"Calling feishu Platform.SendFile with rctx not created by this feishu platform (e.g. a replyContext from telegram, a raw message ID string, or nil) at platform/feishu/feishu.go:3314.","commonSituations":"Routing an engine send across platforms with the wrong platform's reply context; caching a replyContext from a removed/re-created platform instance; tests passing a mock context.","solutions":["Ensure SendFile is only called with the replyContext produced by the same feishu Platform instance's Reply/消息 handling path.","Do not cache replyContext values across platform restarts; re-derive from the incoming message.","If bridging platforms, re-create the correct platform's context instead of forwarding the wrong one."],"exampleFix":"// before\ncrossPlatform.ReplyCtx = telegramCtx\nfeishu.SendFile(ctx, crossPlatform.ReplyCtx, file) // panics into this error\n// after\nfeishu.SendFile(ctx, feishuReplyCtxFromMessage, file)","handlingStrategy":"type-guard","validationCode":"if _, ok := rctx.(feishu.replyContext); !ok {\n    return errors.New(\"SendFile requires a feishu replyContext\")\n}","typeGuard":"func isFeishuReplyContext(rc any) bool {\n    _, ok := rc.(replyContext)\n    return ok\n}","tryCatchPattern":"if err := p.SendFile(ctx, rc, file); err != nil {\n    if strings.Contains(err.Error(), \"invalid reply context type\") {\n        // caller passed wrong platform's context; fix routing\n    }\n}","preventionTips":["Never forward reply contexts between different platform adapters.","Derive replyContext fresh from the current incoming message, not from caches.","Keep replyContext unexported so other packages cannot construct or confuse it."],"tags":["feishu","type-assertion","internal-contract"],"backgroundTag":"incompatible-source-type","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"}