chenhg5/cc-connect · error
%s: refresh card: %w
Error message
%s: refresh card: %w
What it means
Wraps a transport-level error from the Lark SDK's Im.Message.Patch call, which is used by the Feishu platform to refresh (update) an already-sent interactive card. The original SDK error (network failure, auth, invalid message_id) is preserved via %w. It is retried transiently via withTransientRetry/withFreshTenantAccessTokenRetry before surfacing.
Source
Thrown at platform/feishu/card.go:78
msgID := p.cardActionMsgIDs[sessionKey]
p.cardActionMsgMu.Unlock()
if msgID == "" {
return fmt.Errorf("%s: no tracked card messageID for session %q", p.tag(), sessionKey)
}
cardJSON := renderCard(card, sessionKey)
req := larkim.NewPatchMessageReqBuilder().
MessageId(msgID).
Body(larkim.NewPatchMessageReqBodyBuilder().
Content(cardJSON).
Build()).
Build()
return p.withTransientRetry(ctx, "refresh card", func() error {
return p.withFreshTenantAccessTokenRetry(ctx, "refresh card", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {
resp, err := client.Im.Message.Patch(ctx, req, options...)
if err != nil {
return fmt.Errorf("%s: refresh card: %w", p.tag(), err)
}
if !resp.Success() {
return fmt.Errorf("%s: refresh card code=%d msg=%s", p.tag(), resp.Code, resp.Msg)
}
return nil
})
})
}
// renderCardMap converts a core.Card into the Feishu Interactive Card map
// using the v1 format. Used both for message API (via renderCard) and
// callback responses (CardActionTriggerResponse).
func renderCardMap(card *core.Card, sessionKey string) map[string]any {
result := map[string]any{
"config": map[string]any{
"wide_screen_mode": true,
},
}View on GitHub (pinned to 4000b2338a)
Solutions
- Check network connectivity to open.feishu.cn (or the configured domain) and retry the operation.
- Verify app_id/app_secret are valid and the token refresh path works (run cc-connect doctor).
- Confirm the message_id being patched still exists (not recalled or deleted).
- Inspect the wrapped SDK error (%w chain) for the underlying Feishu error code.
Defensive patterns
Strategy: retry
Try / catch
// caller
if err := p.refreshCard(ctx, req); err != nil {
slog.Warn("feishu: card refresh failed; card may be stale", "err", err)
// non-fatal: keep session running, stale card degrades gracefully
} Prevention
- Treat card refresh failures as non-fatal and degrade to text updates.
- Monitor Feishu API status and token refresh logs.
- Don't patch recalled messages; track recall state first.
When it happens
Trigger: Calling the card refresh path (progress/streaming card updates) when client.Im.Message.Patch returns err: network outage, expired/invalid tenant_access_token after retries, invalid message_id, or card schema rejected at transport level.
Common situations: Feishu API outage or rate limiting during long streaming sessions; message recalled/deleted so Patch target no longer exists; app credentials rotated mid-run causing token fetch failures.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- %s: refresh card code=%d msg=%s
- redirected to unsupported image URL
- remote image host resolved to no usable IPs
- remote returned non-zero code
- decode response: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/b31d937a58674c71.
Report an issue: GitHub.