larksuite/cli · error

connection check: api error code=%d msg=%q

Error message

connection check: api error code=%d msg=%q

What it means

The connection-check endpoint can return HTTP 200 with an application-level error inside the JSON envelope (code != 0); Go's json.Unmarshal succeeds but online_instance_cnt would misleadingly decode as 0. To distinguish a verified zero connections from a failed check, this error is raised with the API's code and msg verbatim. It represents a server-side rejection of the request, not a transport or parsing problem.

Source

Thrown at internal/event/consume/remote_preflight.go:34

// CheckRemoteConnections returns the count of active WebSocket connections for this app.
func CheckRemoteConnections(ctx context.Context, client APIClient) (int, error) {
	raw, err := client.CallAPI(ctx, "GET", "/open-apis/event/v1/connection", nil)
	if err != nil {
		return 0, fmt.Errorf("connection check: %w", err)
	}
	var result struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
		Data struct {
			OnlineInstanceCnt int `json:"online_instance_cnt"`
		} `json:"data"`
	}
	if err := json.Unmarshal(raw, &result); err != nil {
		return 0, fmt.Errorf("connection check: decode: %w (body=%s)", err, truncateForError(raw))
	}
	// Distinguish "verified zero" from "check failed" — non-zero code decodes Cnt=0.
	if result.Code != 0 {
		return 0, fmt.Errorf("connection check: api error code=%d msg=%q", result.Code, result.Msg)
	}
	return result.Data.OnlineInstanceCnt, nil
}

// truncateForError bounds length and collapses control chars to defang log injection.
func truncateForError(b []byte) string {
	const max = 256
	s := event.TruncateDiagnostic(string(b), max, "…(truncated)")
	out := make([]byte, 0, len(s))
	for _, r := range s {
		if r == '\n' || r == '\r' || r == '\t' {
			out = append(out, ' ')
			continue
		}
		out = append(out, string(r)...)
	}
	return string(out)
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read code= and msg= from the error and look up that code in the Lark/Feishu API error code docs for the exact cause.
  2. Verify the app credentials and that the app has long-connection/event subscription enabled.
  3. Check scopes/permissions granted to the app for event connections.
  4. Retry with backoff if the code indicates throttling; fix configuration if it indicates auth/permission.
Defensive patterns

Strategy: type-guard

Validate before calling

// After decoding, check the envelope code before trusting online_instance_cnt
var result struct {
	Code int `json:"code"`
	Msg  string `json:"msg"`
	Data struct{ OnlineInstanceCnt int `json:"online_instance_cnt"` } `json:"data"`
}
if result.Code != 0 {
	// treat as API-level failure, not a zero-connection reading
}

Type guard

func isAPISuccess(err error) bool {
	return err == nil || !strings.Contains(err.Error(), "api error code=")
}

Try / catch

cnt, err := consume.CheckRemoteConnections(ctx, client)
if err != nil {
	var code, msg int
	if _, scan := fmt.Sscanf(err.Error(), "connection check: api error code=%d", &code); scan == nil {
		switch code {
		case 99991663, 99991661: // token invalid/expired (example codes)
			refreshTokenAndRetry()
		default:
			log.Fatalf("connection check rejected: code=%d", code)
		}
	}
}

Prevention

When it happens

Trigger: CallAPI succeeded and JSON decoded, but result.Code is non-zero on GET /open-apis/event/v1/connection — e.g. invalid app credentials, app not enabled for long connections, or service-side rejection codes.

Common situations: Wrong app_id/secret configured for the consumer, app lacking the event/long-connection entitlement, tenant-side rate limiting or permission errors returned as app-level codes.

Related errors


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