sipeed/picoclaw · error
feishu delete: %w
Error message
feishu delete: %w
What it means
FeishuChannel.deleteMessageAPI called lark SDK Im.V1.Message.Delete and the SDK returned a transport-level error before a business response could be parsed. The SDK error is wrapped with the 'feishu delete:' prefix; there is no Feishu code to inspect.
Source
Thrown at pkg/channels/feishu/feishu_64.go:284
}
// DeleteMessage implements channels.MessageDeleter.
func (c *FeishuChannel) DeleteMessage(ctx context.Context, chatID, messageID string) error {
deleteFn := c.deleteMessageFn
if deleteFn == nil {
deleteFn = c.deleteMessageAPI
}
return deleteFn(ctx, chatID, messageID)
}
func (c *FeishuChannel) deleteMessageAPI(ctx context.Context, chatID, messageID string) error {
req := larkim.NewDeleteMessageReqBuilder().
MessageId(messageID).
Build()
resp, err := c.client.Im.V1.Message.Delete(ctx, req)
if err != nil {
return fmt.Errorf("feishu delete: %w", err)
}
if !resp.Success() {
c.invalidateTokenOnAuthError(resp.Code)
return fmt.Errorf("feishu delete api error (code=%d msg=%s)", resp.Code, resp.Msg)
}
return nil
}
// SendPlaceholder implements channels.PlaceholderCapable.
// Sends an interactive card with placeholder text and returns its message ID.
func (c *FeishuChannel) SendPlaceholder(ctx context.Context, chatID string) (string, error) {
if !c.bc.Placeholder.Enabled {
logger.DebugCF("feishu", "Placeholder disabled, skipping", map[string]any{
"chat_id": chatID,
})
return "", nil
}
View on GitHub (pinned to 49183d7e8d)
Solutions
- Retry the delete with backoff - placeholders cleanup is time-tolerant
- If retries keep failing, check connectivity to open.feishu.cn and proxy config
- Treat leftover undeleted placeholders as cosmetic: log and move on rather than blocking the pipeline
Example fix
// before
_ = ch.DeleteMessage(ctx, chatID, msgID) // one-shot, silent loss
// after
var err error
for i := 0; i < 3; i++ {
if err = ch.DeleteMessage(ctx, chatID, msgID); err == nil {
break
}
time.Sleep(time.Duration(i+1) * 300 * time.Millisecond)
}
if err != nil {
logger.Warn("placeholder cleanup failed", "msg_id", msgID, "err", err)
} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
func isDeleteTransportError(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "feishu delete: ") && !strings.Contains(err.Error(), "feishu delete api error")
} Try / catch
err := ch.DeleteMessage(ctx, chatID, msgID)
for i := 0; isDeleteTransportError(err) && i < 3; i++ {
time.Sleep(time.Duration(i+1) * 300 * time.Millisecond)
err = ch.DeleteMessage(ctx, chatID, msgID)
}
if err != nil { logger.Warn("placeholder cleanup failed", "msg_id", msgID, "err", err) } Prevention
- Treat placeholder cleanup as best-effort; never block the reply pipeline on it
- Retry only transport-class deletes, never business-code deletes
- Deduplicate delete calls after retries to avoid double-delete
- Monitor delete failures in aggregate - spikes indicate network issues
When it happens
Trigger: DELETE /open-apis/im/v1/messages/:message_id fails at the network layer: timeout, connection refused/reset, DNS failure, or an unparseable HTTP response.
Common situations: Transient connectivity loss when cleaning up placeholder messages; proxy/TLS issues in the deployment network; Feishu edge briefly unavailable; deletion burst hitting socket limits.
Related errors
- feishu edit: %w
- feishu delete api error (code=%d msg=%s)
- feishu react: %w
- feishu send text: %w
- feishu edit api error (code=%d msg=%s)
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/2f7e7f78deff1feb.
Report an issue: GitHub.