chenhg5/cc-connect · error

parse response: %w

Error message

parse response: %w

What it means

Thrown by the Feishu platform adapter when the HTTP response body of a 'get bot info' API call cannot be unmarshalled into the expected struct (code + bot.open_id). It wraps the underlying json.Unmarshal error, so the cause is a malformed or unexpected response payload, not a logic error in the caller.

Source

Thrown at platform/feishu/feishu.go:3824

	}
	return -1
}

// fetchBotOpenID retrieves the bot's open_id via the Feishu bot info API.
func (p *Platform) fetchBotOpenID() (string, error) {
	resp, err := p.client.Get(context.Background(),
		"/open-apis/bot/v3/info", nil, larkcore.AccessTokenTypeTenant)
	if err != nil {
		return "", fmt.Errorf("api call: %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("parse response: %w", err)
	}
	if result.Code != 0 {
		return "", fmt.Errorf("api code=%d", result.Code)
	}
	return result.Bot.OpenID, nil
}

func isBotMentioned(mentions []*larkim.MentionEvent, botOpenID string) bool {
	for _, m := range mentions {
		if m.Id != nil && m.Id.OpenId != nil && *m.Id.OpenId == botOpenID {
			return true
		}
	}
	return false
}

// filterQuotedFilesForUser applies the two gating rules for issue #1560
// without downloading anything yet:

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Log resp.RawBody alongside the wrapped error to see the actual payload returned.
  2. Verify the app/api base URL (Feishu vs Lark domain) and that no proxy is intercepting the request.
  3. Retry the call — transient network truncation often resolves.
  4. Upgrade the larksuite/oapi-sdk and re-check the response schema if Feishu changed the endpoint format.

Example fix

// before
if err := json.Unmarshal(resp.RawBody, &result); err != nil {
	return "", fmt.Errorf("parse response: %w", err)
}
// after
if err := json.Unmarshal(resp.RawBody, &result); err != nil {
	return "", fmt.Errorf("parse response: %w (body: %.200s)", err, string(resp.RawBody))
}
Defensive patterns

Strategy: try-catch

Validate before calling

if len(resp.RawBody) == 0 || resp.RawBody[0] != '{' {
	// body is not JSON; do not attempt Unmarshal
}

Type guard

func isValidJSONBody(b []byte) bool { return json.Valid(b) }

Try / catch

botID, err := getBotOpenID(ctx)
if err != nil {
	var parseErr *json.UnmarshalTypeError
	if errors.As(err, &parseErr) { /* schema changed: log body, alert */ }
	return fmt.Errorf("bot info unavailable: %w", err)
}

Prevention

When it happens

Trigger: The call to fetch the bot's own open_id receives a 200 response whose RawBody is not valid JSON, or its shape differs from {code, bot.open_id} (e.g. an HTML error page from a proxy, truncated body, or Feishu API version change).

Common situations: Corporate proxies/gateways returning HTML interstitials, intermittent network truncation, wrong API base URL pointing at a non-Feishu endpoint, or Feishu changing the response schema for the bot-info endpoint.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/03440ae35acec2bf. Report an issue: GitHub.