{"record":{"id":"40cdc8d37880bb3e","repo":"chenhg5/cc-connect","slug":"s-refresh-card-code-d-msg-s","errorCode":null,"errorMessage":"%s: refresh card code=%d msg=%s","messagePattern":"(.+?): refresh card code=(.+?) msg=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/card.go","lineNumber":81,"sourceCode":"\tif msgID == \"\" {\n\t\treturn fmt.Errorf(\"%s: no tracked card messageID for session %q\", p.tag(), sessionKey)\n\t}\n\n\tcardJSON := renderCard(card, sessionKey)\n\treq := larkim.NewPatchMessageReqBuilder().\n\t\tMessageId(msgID).\n\t\tBody(larkim.NewPatchMessageReqBodyBuilder().\n\t\t\tContent(cardJSON).\n\t\t\tBuild()).\n\t\tBuild()\n\treturn p.withTransientRetry(ctx, \"refresh card\", func() error {\n\t\treturn p.withFreshTenantAccessTokenRetry(ctx, \"refresh card\", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {\n\t\t\tresp, err := client.Im.Message.Patch(ctx, req, options...)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s: refresh card: %w\", p.tag(), err)\n\t\t\t}\n\t\t\tif !resp.Success() {\n\t\t\t\treturn fmt.Errorf(\"%s: refresh card 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// renderCardMap converts a core.Card into the Feishu Interactive Card map\n// using the v1 format. Used both for message API (via renderCard) and\n// callback responses (CardActionTriggerResponse).\nfunc renderCardMap(card *core.Card, sessionKey string) map[string]any {\n\tresult := map[string]any{\n\t\t\"config\": map[string]any{\n\t\t\t\"wide_screen_mode\": true,\n\t\t},\n\t}\n\tif card == nil {\n\t\treturn result\n\t}","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/card.go#L63-L99","documentation":"Raised when the Lark Im.Message.Patch call completes but resp.Success() is false, i.e. Feishu returned an application-level error. The Feishu business code and message are embedded so the exact API failure (e.g. permission, invalid card JSON) can be identified. Same retry wrapping applies as transport errors.","triggerScenarios":"Patch request reaches Feishu but is rejected: invalid card JSON schema, bot lacks im:message permission for update, message_id not found (code 230002), or rate-limit/business code returned in resp.Code.","commonSituations":"Insufficient scopes on the Feishu app after an app config change; card content exceeding Feishu size limits during long streams; patching a message whose chat the bot was removed from.","solutions":["Look up the embedded code=%d in Feishu's error-code docs and fix the specific cause.","Ensure the app has im:message:update (patch) scope and the bot is still in the chat.","Reduce card payload size if code indicates card too large or invalid.","Verify message_id validity; skip refresh if the message was recalled."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"var feishuErr *larkcore.APIError\nif errors.As(err, &feishuErr) {\n    slog.Error(\"feishu patch rejected\", \"code\", feishuErr.Code, \"msg\", feishuErr.Msg)\n}","preventionTips":["Grant the app im:message update scope before deployment.","Keep bot in the target chat for the session's lifetime.","Keep card payloads under Feishu size limits."],"tags":["feishu","lark-sdk","api-error","card-refresh"],"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"}