sipeed/picoclaw · warning

bot info api error (code=%d)

Error message

bot info api error (code=%d)

What it means

The bot-info endpoint answered with JSON but code != 0: Feishu rejected the call at the business level. Most common is 99991663/99991661 (invalid or expired tenant_access_token), i.e. the app_id/app_secret pair is wrong or the token cache is stale; invalidateTokenOnAuthError(result.Code) already ran so the SDK will re-auth on the next call. Start() logs and continues, degraded.

Source

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

		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")
	}

	c.botOpenID.Store(result.Bot.OpenID)
	logger.InfoCF("feishu", "Fetched bot open_id from API", map[string]any{
		"open_id": result.Bot.OpenID,
	})
	return nil
}

// isBotMentioned checks if the bot was @mentioned in the message.
func (c *FeishuChannel) isBotMentioned(message *larkim.EventMessage) bool {
	if message.Mentions == nil {
		return false
	}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Map the code: 99991661/99991663 means verify app_id/app_secret in the Feishu console and redeploy
  2. If credentials are correct, the token invalidation already scheduled a refresh - retry the operation
  3. Other codes: check the Feishu API docs for /bot/v3/info specifics
  4. Alert on this at startup when mention detection is a required feature

Example fix

// before: only logged, easy to miss
// logger.ErrorCF("feishu", "Failed to fetch bot open_id ...")

// after: make credential-class failures loud
if err := c.fetchBotOpenID(ctx); err != nil {
	if strings.Contains(err.Error(), "bot info api error") {
		logger.Error("feishu credentials likely invalid", "err", err)
	}
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

func isBotInfoAuthFailure(err error) bool {
	if err == nil { return false }
	m := regexp.MustCompile(`bot info api error \(code=(\d+)\)`).FindStringSubmatch(err.Error())
	if m == nil { return false }
	code, _ := strconv.Atoi(m[1])
	return code == 99991661 || code == 99991663
}

Try / catch

err := fetchBotInfo(ctx)
if isBotInfoAuthFailure(err) {
	// invalidateTokenOnAuthError already cleared the cached token:
	// one retry lets the SDK mint a fresh tenant_access_token
	time.Sleep(time.Second)
	err = fetchBotInfo(ctx)
}
if err != nil {
	logger.Warn("bot open_id unavailable; @mention detection degraded", "err", err)
}

Prevention

When it happens

Trigger: fetchBotOpenID with bad app credentials (wrong secret, deleted app, wrong app_id), or a stale tenant token after credential rotation.

Common situations: Secret rotated in Feishu console but not in deployment config; sandbox vs production credentials mixed up; app disabled by admin.

Related errors


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