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

  1. Upgrade lark-cli to the latest version in case the response schema changed
  2. Check the app actually has bot capability enabled in the developer console
  3. 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

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


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/bc474e5785d7e666. Report an issue: GitHub.