{"record":{"id":"ba47eafc3a8b3b40","repo":"sipeed/picoclaw","slug":"feishu-edit-api-error-code-d-msg-s","errorCode":null,"errorMessage":"feishu edit api error (code=%d msg=%s)","messagePattern":"feishu edit api error \\(code=(.+?) msg=(.+?)\\)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/channels/feishu/feishu_64.go","lineNumber":263,"sourceCode":"// Uses Message.Patch to update an interactive card message.\nfunc (c *FeishuChannel) EditMessage(ctx context.Context, chatID, messageID, content string) error {\n\tcardContent, err := buildMarkdownCard(content)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"feishu edit: card build failed: %w\", err)\n\t}\n\n\treq := larkim.NewPatchMessageReqBuilder().\n\t\tMessageId(messageID).\n\t\tBody(larkim.NewPatchMessageReqBodyBuilder().Content(cardContent).Build()).\n\t\tBuild()\n\n\tresp, err := c.client.Im.V1.Message.Patch(ctx, req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"feishu edit: %w\", err)\n\t}\n\tif !resp.Success() {\n\t\tc.invalidateTokenOnAuthError(resp.Code)\n\t\treturn fmt.Errorf(\"feishu edit api error (code=%d msg=%s)\", resp.Code, resp.Msg)\n\t}\n\treturn nil\n}\n\n// DeleteMessage implements channels.MessageDeleter.\nfunc (c *FeishuChannel) DeleteMessage(ctx context.Context, chatID, messageID string) error {\n\tdeleteFn := c.deleteMessageFn\n\tif deleteFn == nil {\n\t\tdeleteFn = c.deleteMessageAPI\n\t}\n\treturn deleteFn(ctx, chatID, messageID)\n}\n\nfunc (c *FeishuChannel) deleteMessageAPI(ctx context.Context, chatID, messageID string) error {\n\treq := larkim.NewDeleteMessageReqBuilder().\n\t\tMessageId(messageID).\n\t\tBuild()\n","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/feishu/feishu_64.go#L245-L281","documentation":"FeishuChannel.EditMessage's Patch call completed and the response parsed, but resp.Success() is false: Feishu returned a non-zero business code. Common codes: 99991661/99991663 (invalid or expired tenant_access_token), 230002 (no permission / bot not in chat), invalid message_id, or the message is not editable (e.g. it was a plain-text fallback message, which cannot be card-patched). invalidateTokenOnAuthError(resp.Code) already ran for auth-class codes.","triggerScenarios":"Message.Patch responds with code!=0: editing a deleted/nonexistent message_id, editing a message the bot lacks permission for, expired tenant token, or patching a non-card message type.","commonSituations":"Editing a placeholder that already fell back to plain text; bot removed from the chat between send and edit; token invalidated by concurrent restarts or credential rotation; message_id from a different tenant/app.","solutions":["Read the code in the message: 99991661/99991663 means auth - let the token refresh (invalidateTokenOnAuthError already triggered) or recheck app credentials","230002/permission codes: confirm the bot is still in the chat and has im:message scope","Invalid message_id or non-editable message: stop patching and delete + resend a fresh message instead","Do not blind-retry permanent business errors; surface them to the pipeline"],"exampleFix":"// before\nif err := ch.EditMessage(ctx, chatID, msgID, content); err != nil {\n\tretry() // wrong: business codes are usually permanent\n}\n\n// after\nerr := ch.EditMessage(ctx, chatID, msgID, content)\nif code, ok := feishuAPICode(err); ok {\n\tswitch code {\n\tcase 99991661, 99991663: // auth: token already invalidated, next call re-auths\n\t\tretrySoon()\n\tdefault:\n\t\tresendAsNewMessage(ctx, chatID, content) // patch impossible\n\t}\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"var feishuCodeRe = regexp.MustCompile(`api error \\(code=(\\d+)`)\n\nfunc feishuErrorCode(err error) (int, bool) {\n\tif err == nil { return 0, false }\n\tm := feishuCodeRe.FindStringSubmatch(err.Error())\n\tif m == nil { return 0, false }\n\tn, _ := strconv.Atoi(m[1])\n\treturn n, true\n}","tryCatchPattern":"if err := ch.EditMessage(ctx, chatID, msgID, content); err != nil {\n\tif code, ok := feishuErrorCode(err); ok {\n\t\tswitch code {\n\t\tcase 99991661, 99991663: // auth: token invalidation already triggered\n\t\t\ttime.Sleep(time.Second); retryOnce()\n\t\tdefault: // permission / bad message_id: permanent\n\t\t\tresendAsNewMessage(ctx, chatID, content)\n\t\t}\n\t}\n}","preventionTips":["Do not retry non-auth business codes; they are deterministic","Refresh-then-retry only 99991661/99991663-class codes","Verify bot membership and im:message scopes before edit-heavy flows","Log code+msg verbatim; they map 1:1 to Feishu's documented error catalog"],"tags":["feishu","api-error","edit","auth","permission","lark-sdk"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}