sipeed/picoclaw · error

feishu edit: %w

Error message

feishu edit: %w

What it means

FeishuChannel.EditMessage called lark SDK Im.V1.Message.Patch and the SDK itself returned a transport-level error (request could not be completed or returned a non-parsable response). The SDK error is wrapped with the 'feishu edit:' prefix; no Feishu business code is available because the response never parsed.

Source

Thrown at pkg/channels/feishu/feishu_64.go:259

	return nil, err
}

// EditMessage implements channels.MessageEditor.
// Uses Message.Patch to update an interactive card message.
func (c *FeishuChannel) EditMessage(ctx context.Context, chatID, messageID, content string) error {
	cardContent, err := buildMarkdownCard(content)
	if err != nil {
		return fmt.Errorf("feishu edit: card build failed: %w", err)
	}

	req := larkim.NewPatchMessageReqBuilder().
		MessageId(messageID).
		Body(larkim.NewPatchMessageReqBodyBuilder().Content(cardContent).Build()).
		Build()

	resp, err := c.client.Im.V1.Message.Patch(ctx, req)
	if err != nil {
		return fmt.Errorf("feishu edit: %w", err)
	}
	if !resp.Success() {
		c.invalidateTokenOnAuthError(resp.Code)
		return fmt.Errorf("feishu edit api error (code=%d msg=%s)", resp.Code, resp.Msg)
	}
	return nil
}

// 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 {

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Retry the edit with short backoff - transport errors are usually transient
  2. If persistent, reproduce with curl against open.feishu.cn to isolate network vs code
  3. Check the card content size; very large patches can exceed intermediary timeouts
  4. Verify client timeout settings on the lark client options

Example fix

// before
return ch.EditMessage(ctx, chatID, msgID, content)

// after
var err error
for i := 0; i < 3; i++ {
	if err = ch.EditMessage(ctx, chatID, msgID, content); err == nil {
		return nil
	}
	if strings.Contains(err.Error(), "feishu edit api error") {
		break // business error: do not blind-retry
	}
	time.Sleep(time.Duration(i+1) * 500 * time.Millisecond)
}
return err
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

func isEditTransportError(err error) bool {
	return err != nil && strings.HasPrefix(err.Error(), "feishu edit: ") && !strings.Contains(err.Error(), "feishu edit api error")
}

Try / catch

err := ch.EditMessage(ctx, chatID, msgID, content)
for i := 0; isEditTransportError(err) && i < 3; i++ {
	time.Sleep(time.Duration(i+1) * 500 * time.Millisecond)
	err = ch.EditMessage(ctx, chatID, msgID, content)
}
return err

Prevention

When it happens

Trigger: PATCH /open-apis/im/v1/messages/:message_id fails at the network layer: timeout, connection reset, DNS failure, or an HTTP response the lark SDK could not decode.

Common situations: Transient network issues between the host and open.feishu.cn; corporate proxy interference; oversized card payload causing slow upload and client timeout; Feishu API briefly unavailable.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/cf594cfd13e53545. Report an issue: GitHub.