larksuite/cli · error

fetch bot info: [%d] %s

Error message

fetch bot info: [%d] %s

What it means

The /bot/v3/info envelope decoded fine but carries a non-zero business code, meaning the Lark API itself rejected the logical request. The message surfaces the API's own code and msg so the developer can map it to Lark's error taxonomy (e.g. permission denied, invalid token).

Source

Thrown at shortcuts/common/runner.go:187

	}
	if resp.StatusCode >= 400 {
		return nil, fmt.Errorf("fetch bot info: HTTP %d", resp.StatusCode)
	}
	// /open-apis/bot/v3/info returns `{code, msg, bot: {...}}` — the bot
	// payload is under "bot", not "data" as the newer Lark API convention.
	var envelope struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
		Data struct {
			OpenID  string `json:"open_id"`
			AppName string `json:"app_name"`
		} `json:"bot"`
	}
	if err := json.Unmarshal(resp.RawBody, &envelope); err != nil {
		return nil, fmt.Errorf("fetch bot info: unmarshal: %w", err)
	}
	if envelope.Code != 0 {
		return nil, fmt.Errorf("fetch bot info: [%d] %s", envelope.Code, envelope.Msg)
	}
	if envelope.Data.OpenID == "" {
		return nil, fmt.Errorf("fetch bot info: open_id is empty")
	}
	return &BotInfo{OpenID: envelope.Data.OpenID, AppName: envelope.Data.AppName}, nil
}

// Ctx returns the context.Context propagated from cmd.Context().
func (ctx *RuntimeContext) Ctx() context.Context { return ctx.ctx }

// getAPIClient returns the cached APIClient, creating it on first use.
// Thread-safe via sync.OnceValues (initialized in newRuntimeContext).
// Falls back to direct construction for test contexts that bypass newRuntimeContext.
func (ctx *RuntimeContext) getAPIClient() (*client.APIClient, error) {
	if ctx.offline {
		return nil, errs.NewValidationError(errs.SubtypeFailedPrecondition, "OpenAPI requests are unavailable during dry-run")
	}
	if ctx.apiClientFunc != nil {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Look up the returned code in Lark's API error docs and apply the mapped fix (scopes, token, app state)
  2. Regenerate/refresh the app access token for the bot identity
  3. Confirm the app is enabled and bot capability is turned on in the developer console
Defensive patterns

Strategy: fallback

Try / catch

info, err := ctx.BotInfo()
if err != nil {
	var apiErr *lark.APIError
	if errors.As(err, &apiErr) { /* map apiErr.Code via Lark docs */ }
	if strings.Contains(err.Error(), "fetch bot info: ["){ /* business code in message: surface to user */ }
	return err
}

Prevention

When it happens

Trigger: envelope.Code != 0 in the bot info response — e.g. invalid app access token, bot capability disabled for the app, or tenant-level restriction on bot info.

Common situations: Token mismatched to tenant/app; app not published/enabled in the tenant; insufficient bot scopes for /bot/v3/info.

Related errors


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