chenhg5/cc-connect · error
%s: send preview: no message ID returned
Error message
%s: send preview: no message ID returned
What it means
Thrown by the Feishu platform's send-preview path after a successful (resp.Success()) Reply or Create message call when the response contains no message_id. The SDK can return success with a nil Data or nil MessageId pointer; since streaming/patch updates key off the message ID, the code treats its absence as a hard failure instead of returning a handle with an empty ID.
Source
Thrown at platform/feishu/feishu.go:5149
resp, err = client.Im.Message.Create(ctx, req, options...)
if err != nil {
return fmt.Errorf("%s: send preview: %w", p.tag(), err)
}
if !resp.Success() {
return fmt.Errorf("%s: send preview code=%d msg=%s", p.tag(), resp.Code, resp.Msg)
}
return nil
})
}); err != nil {
return nil, err
}
if resp.Data != nil && resp.Data.MessageId != nil {
msgID = *resp.Data.MessageId
}
}
if msgID == "" {
return nil, fmt.Errorf("%s: send preview: no message ID returned", p.tag())
}
return &feishuPreviewHandle{messageID: msgID, chatID: chatID, cardID: cardID}, nil
}
// createCardEntity calls the cardkit-v1 Create Card Entity API
// (POST /open-apis/cardkit/v1/cards) and returns the card_id.
//
// The card_id is required to drive the streaming text update path
// (PUT /open-apis/cardkit/v1/cards/{card_id}/elements/{element_id}/content).
// If this call fails the caller should fall back to inline card JSON via the
// regular Im.Message.Create path; the rich card will still render but without
// native typewriter streaming.
func (p *Platform) createCardEntity(ctx context.Context, cardJSON string) (string, error) {
body := map[string]any{
"type": "card_json",
"data": cardJSON,
}View on GitHub (pinned to 4000b2338a)
Solutions
- Check that resp.Data and resp.Data.MessageId are being populated — upgrade github.com/larksuite/oapi-sdk-go to the latest version so CreateMessageResp/ReplyMessageResp shapes match the current API
- Log resp.RawBody on this path to see what Feishu actually returned and confirm whether the API call itself succeeded
- Verify the bot has im:message:send_as_bot (or im:message) permission and is a member of the target chat
- If this recurs after a Feishu API change, fall back to the inline-card-JSON send path instead of failing the preview
Example fix
// before
if msgID == "" {
return nil, fmt.Errorf("%s: send preview: no message ID returned", p.tag())
}
// after
if msgID == "" {
slog.Warn(p.tag()+": send preview: no message ID in response, falling back", "raw", string(resp.RawBody))
return nil, fmt.Errorf("%s: send preview: no message ID returned", p.tag())
} Defensive patterns
Strategy: type-guard
Validate before calling
if resp == nil || resp.Data == nil || resp.Data.MessageId == nil || *resp.Data.MessageId == "" {
// treat as preview failure and fall back to non-streaming send
} Type guard
func messageIDFromResp(resp *larkim.CreateMessageResp) string {
if resp == nil || resp.Data == nil || resp.Data.MessageId == nil {
return ""
}
return *resp.Data.MessageId
} Try / catch
if err != nil {
var noID *NoMessageIDError
if errors.As(err, &noID) {
// fall back to inline-card-JSON send without streaming
}
} Prevention
- Always check resp.Data and resp.Data.MessageId for nil before dereferencing
- Pin and regularly upgrade the larksuite oapi-sdk-go version
- Keep the inline-card-JSON fallback wired so a missing ID degrades gracefully
- Log RawBody on anomalous responses to catch Feishu API drift early
When it happens
Trigger: client.Im.Message.Reply or client.Im.Message.Create returned resp.Success()==true but resp.Data==nil or resp.Data.MessageId==nil; e.g. Lark IM API returning 200 with an empty/oddly-shaped body, or an SDK version whose response struct no longer populates MessageId for interactive messages.
Common situations: Bot lacks im:message send scope on the target chat in a way that degrades the response; proxy/gateway stripping the body; Feishu API behavior change or larksuite SDK version mismatch; sending to a chat where the interactive card is accepted but the ID is not echoed back.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- parse response: %w
- api code=%d
- %s: chatID is empty, cannot send new message
- %s: reply api call: %w
- %s: reply failed code=%d msg=%s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/a580e0ef6bfb5705.
Report an issue: GitHub.