larksuite/cli · warning
open_id is empty
Error message
open_id is empty
What it means
fetchBotInfo validates the bot-info API envelope and fails when Data.OpenID is empty even though the API reported success (Code==0). This is a defensive invariant check: a bot identity diagnosis is meaningless without an open_id, so the library treats a success envelope lacking one as an error rather than returning a hollow botInfo. It propagates to diagnoseBot/diagnoseExternalBot.
Source
Thrown at internal/identitydiag/diagnostics.go:433
parseErr := json.Unmarshal(body, &envelope)
if resp.StatusCode >= 400 {
// Lark error responses are usually `{code, msg}` envelopes even on
// non-2xx — surface them when present so callers see why bot auth
// was rejected, not just the bare HTTP code.
if parseErr == nil && envelope.Code != 0 {
return nil, fmt.Errorf("HTTP %d: [%d] %s", resp.StatusCode, envelope.Code, envelope.Msg)
}
return nil, fmt.Errorf("HTTP %d", resp.StatusCode)
}
if parseErr != nil {
return nil, fmt.Errorf("parse response: %w", parseErr)
}
if envelope.Code != 0 {
return nil, fmt.Errorf("[%d] %s", envelope.Code, envelope.Msg)
}
if envelope.Data.OpenID == "" {
return nil, errors.New("open_id is empty")
}
return &botInfo{OpenID: envelope.Data.OpenID, AppName: envelope.Data.AppName}, nil
}
func fillTokenFields(id *Identity, token *larkauth.StoredUAToken) {
id.TokenStatus = larkauth.TokenStatus(token)
id.Scope = token.Scope
id.ExpiresAt = formatMillis(token.ExpiresAt)
id.RefreshExpiresAt = formatMillis(token.RefreshExpiresAt)
id.GrantedAt = formatMillis(token.GrantedAt)
}
func formatMillis(ms int64) string {
if ms <= 0 {
return ""
}
return time.UnixMilli(ms).Format(time.RFC3339)
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Upgrade lark-cli to the latest version in case the response schema changed
- Check the app actually has bot capability enabled in the developer console
- Inspect the raw API response (log_id / gateway) to confirm whether the server truly returned an empty open_id
Defensive patterns
Strategy: try-catch
Validate before calling
if envelope.Code == 0 && envelope.Data.OpenID == "" {
// treat as suspect response before consuming
} Type guard
func botInfoValid(b *botInfo) bool { return b != nil && b.OpenID != "" } Try / catch
info, err := fetchBotInfo(ctx, client)
if err != nil {
// includes 'open_id is empty' — retry once, then surface diagnostics
} Prevention
- Pin/test against current bot-info API versions
- Validate bot capability is enabled before diagnosing
- Log raw envelopes to detect shape drift early
- Fail fast on success envelopes with empty required fields
When it happens
Trigger: Calling diagnoseBot/diagnoseExternalBot where the bot-info endpoint returns Code==0 but Data.OpenID is "" — e.g. an API behavior change, an unexpected app type, or a stubbed/proxied response missing fields.
Common situations: Feishu/Lark API version change altering the response shape; a gateway or mock returning an empty payload with code 0; diagnosing an app type that has no bot open_id.
Related errors
- invalid identity %q: must be user|bot
- decode application response: %w
- decode app_versions response: %w
- failed to verify user identity: %w
- create HTTP client: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/bc474e5785d7e666.
Report an issue: GitHub.