sipeed/picoclaw · warning

bot info request: %w

Error message

bot info request: %w

What it means

FeishuChannel.fetchBotOpenID performs a raw larkcore request to GET /open-apis/bot/v3/info and the SDK failed at the transport level before a response parsed. Start() only logs this as a warning and continues: the bot keeps running, but @mention detection may not work because botOpenID stays unset.

Source

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

		inboundCtx.SpaceType = "tenant"
		inboundCtx.SpaceID = *sender.TenantKey
	}

	c.HandleInboundContext(ctx, chatID, content, mediaRefs, inboundCtx, senderInfo)
	return nil
}

// --- Internal helpers ---

// fetchBotOpenID calls the Feishu bot info API to retrieve and store the bot's open_id.
func (c *FeishuChannel) fetchBotOpenID(ctx context.Context) error {
	resp, err := c.client.Do(ctx, &larkcore.ApiReq{
		HttpMethod:                http.MethodGet,
		ApiPath:                   "/open-apis/bot/v3/info",
		SupportedAccessTokenTypes: []larkcore.AccessTokenType{larkcore.AccessTokenTypeTenant},
	})
	if err != nil {
		return fmt.Errorf("bot info request: %w", err)
	}

	var result struct {
		Code int `json:"code"`
		Bot  struct {
			OpenID string `json:"open_id"`
		} `json:"bot"`
	}
	if err := json.Unmarshal(resp.RawBody, &result); err != nil {
		return fmt.Errorf("bot info parse: %w", err)
	}
	if result.Code != 0 {
		c.invalidateTokenOnAuthError(result.Code)
		return fmt.Errorf("bot info api error (code=%d)", result.Code)
	}
	if result.Bot.OpenID == "" {
		return fmt.Errorf("bot info: empty open_id")
	}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Retry the start or trigger a later open_id refresh - the failure is startup-degrading, not fatal
  2. Ensure egress to open.feishu.cn is available at container boot (init containers or readiness hooks)
  3. If mention detection matters, monitor for the 'Failed to fetch bot open_id' log and alert
  4. Consider memoizing and refreshing the open_id lazily on first mention check

Example fix

// before
if err := c.fetchBotOpenID(ctx); err != nil { /* logged, botOpenID empty */ }

// after
var err error
for i := 0; i < 3 && err != nil; i++ {
	time.Sleep(time.Duration(i) * time.Second) // wait for network readiness
	err = c.fetchBotOpenID(ctx)
}
if err != nil {
	logger.Warn("bot open_id unavailable; @mention detection degraded")
}
Defensive patterns

Strategy: retry

Validate before calling

// wait for network readiness before starting the channel
func waitForEgress(host string, timeout time.Duration) bool {
	deadline := time.Now().Add(timeout)
	for time.Now().Before(deadline) {
		if _, err := net.DialTimeout("tcp", host+":443", time.Second); err == nil {
			return true
		}
		time.Sleep(500 * time.Millisecond)
	}
	return false
}

Type guard

null

Try / catch

// Start already degrades gracefully; retry only to preserve mention detection
err := ch.Start(ctx)
if err == nil && !ch.HasBotOpenID() {
	logger.Warn("bot open_id missing; will retry fetch", "err", lastFetchErr)
	go func() { _ = ch.RefreshBotOpenID(ctx) }() // or restart the channel later
}

Prevention

When it happens

Trigger: The channel's first API call at startup hits a network failure: DNS not ready (common in containers at boot), proxy down, connection refused to open.feishu.cn.

Common situations: Container startup racing DNS/network readiness; egress firewall allowing webhooks but blocking the info endpoint; flaky first-hop connectivity.

Related errors


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