{"record":{"id":"ab64d3abc22e1bad","repo":"chenhg5/cc-connect","slug":"s-delete-preview-message-code-d-msg-s","errorCode":null,"errorMessage":"%s: delete preview message code=%d msg=%s","messagePattern":"(.+?): delete preview message code=(.+?) msg=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/feishu.go","lineNumber":5454,"sourceCode":"\t\treturn core.ErrNotSupported\n\t}\n\n\th, ok := previewHandle.(*feishuPreviewHandle)\n\tif !ok {\n\t\treturn fmt.Errorf(\"%s: invalid preview handle type %T\", p.tag(), previewHandle)\n\t}\n\n\treq := larkim.NewDeleteMessageReqBuilder().\n\t\tMessageId(h.messageID).\n\t\tBuild()\n\treturn p.withTransientRetry(ctx, \"delete preview message\", func() error {\n\t\treturn p.withFreshTenantAccessTokenRetry(ctx, \"delete preview message\", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {\n\t\t\tresp, err := client.Im.Message.Delete(ctx, req, options...)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s: delete preview message: %w\", p.tag(), err)\n\t\t\t}\n\t\t\tif !resp.Success() {\n\t\t\t\treturn fmt.Errorf(\"%s: delete preview message code=%d msg=%s\", p.tag(), resp.Code, resp.Msg)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t})\n}\n\n// SendAudio uploads audio bytes to Feishu and sends a voice message.\n// Implements core.AudioSender interface.\n// Feishu audio messages require opus format; non-opus input is converted via ffmpeg.\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(\"%s: SendAudio: invalid reply context type %T\", p.tag(), rctx)\n\t}\n\n\tif format != \"opus\" {\n\t\tconverted, err := core.ConvertAudioToOpus(ctx, audio, format)\n\t\tif err != nil {","sourceCodeStart":5436,"sourceCodeEnd":5472,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L5436-L5472","documentation":"The Feishu API responded successfully at the HTTP layer but returned a non-success business code in the response body. The error carries the platform tag, the numeric Feishu error code, and the human-readable msg from Feishu. Unlike 1231 this is a definitive API-level rejection, not a transport failure, so retries with a fresh token have already been attempted.","triggerScenarios":"client.Im.Message.Delete succeeds over HTTP but resp.Success() is false — e.g. code 99991663/99991661 (token/permission), code 230002 (message not found, already deleted), or other im:message deletion permission errors for the bot.","commonSituations":"Bot lacks im:message:delete (or im:message) scope; the preview message was already deleted by a user or retention policy; the bot tries to delete a message it did not send; app credential misconfiguration in config.toml.","solutions":["Read the code=%d in the message and look it up in Feishu's error-code docs","Grant the bot the im:message deletion scope and republish the app version","Treat 'message already deleted' codes as benign and skip","Verify the message_id belongs to a message sent by this bot"],"exampleFix":"// before: treating all failures as fatal\nif err := p.DeletePreview(ctx, h); err != nil { return err }\n// after\nif err := p.DeletePreview(ctx, h); err != nil && !strings.Contains(err.Error(), \"code=230002\") { return err }","handlingStrategy":"try-catch","validationCode":"// verify bot scopes before calling: ensure im:message / im:message:delete granted in Feishu admin console","typeGuard":null,"tryCatchPattern":"if err := p.DeletePreview(ctx, h); err != nil {\n    var codeErr *FeishuAPIError // parse code=N from message if needed\n    if strings.Contains(err.Error(), \"230002\") { return nil } // already deleted: benign\n    return err\n}","preventionTips":["Grant and publish im:message deletion scope","Treat 'already deleted' codes as success","Correlate code numbers with Feishu error docs","Keep app versions republished after scope changes"],"tags":["feishu","api-error","permissions","error-code"],"backgroundTag":"api-error-response","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"}