chenhg5/cc-connect · warning
%s: stream rich card text: parse response: %w
Error message
%s: stream rich card text: parse response: %w
What it means
The streaming element-content PUT returned HTTP 200 but the body could not be unmarshaled into {code,msg}. The frame's success cannot be determined, so the code errors out. Usually means the body is not Cardkit JSON — proxy page, empty body, or an unexpected envelope.
Source
Thrown at platform/feishu/feishu.go:5246
}
var apiResp *larkcore.ApiResp
if err := p.withFreshTenantAccessTokenRetry(ctx, "stream rich card text", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {
var err error
apiResp, err = client.Put(ctx, apiPath, body, larkcore.AccessTokenTypeTenant, options...)
return err
}); err != nil {
return fmt.Errorf("%s: stream rich card text: %w", p.tag(), err)
}
if apiResp == nil || apiResp.StatusCode != http.StatusOK {
return fmt.Errorf("%s: stream rich card text: HTTP status %d", p.tag(), apiResp.StatusCode)
}
var resp struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {
return fmt.Errorf("%s: stream rich card text: parse response: %w", p.tag(), err)
}
if resp.Code != 0 {
err := classifyFeishuCardAPIError("stream rich card text", resp.Code, resp.Msg)
if errors.Is(err, errFeishuCardRateLimited) {
slog.Debug(p.tag()+": stream rich card text rate limited; skipping frame", "code", resp.Code)
return nil
}
return fmt.Errorf("%s: %w", p.tag(), err)
}
return nil
}
// UpdateMessage edits an existing card message identified by previewHandle.
// Uses the Patch API (HTTP PATCH) which is required for interactive card messages.
func (p *Platform) UpdateMessage(ctx context.Context, previewHandle any, content string) error {
if !p.useInteractiveCard {
return core.ErrNotSupported
}View on GitHub (pinned to 4000b2338a)
Solutions
- Log string(apiResp.RawBody) when this fires to capture the actual body
- Verify no proxy/CDN sits between the host and open.feishu.cn
- Update the inline struct if Feishu changed the response shape
- Since frames are best-effort, consider downgrading to a warning and continuing the stream
Example fix
// before
if err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {
return fmt.Errorf("%s: stream rich card text: parse response: %w", p.tag(), err)
}
// after
if err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {
slog.Warn(p.tag()+": stream rich card text: unparseable response; continuing", "err", err, "raw", string(apiResp.RawBody))
return nil // frames are best-effort; final Patch converges
} Defensive patterns
Strategy: try-catch
Validate before calling
if apiResp == nil || len(apiResp.RawBody) == 0 {
// skip frame; final Patch will converge
} Try / catch
if err := p.StreamRichCardText(ctx, h, text); err != nil {
if strings.Contains(err.Error(), "parse response") {
slog.Debug("unparseable stream frame response; skipping frame")
// continue streaming
}
} Prevention
- Log RawBody on parse failures to detect proxy or schema drift
- Skip-and-continue on frame parse errors; final Patch fixes content
- Ensure no transparent proxy rewrites Feishu API responses
- Update the response struct promptly when Feishu changes the envelope
When it happens
Trigger: json.Unmarshal(apiResp.RawBody, &resp) fails on the PUT response: empty RawBody, HTML from an intercepting proxy, or a response whose code field is not an integer (schema drift).
Common situations: Corporate proxy injecting pages; Feishu returning an undocumented envelope for this endpoint in some regions; truncated responses under heavy streaming load.
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
- %s: create card entity: parse response: %w
- %s: stream rich card text: %w
- %s: stream rich card text: HTTP status %d
- decode response: %w
- decode: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/3e2f61bc6e13428d.
Report an issue: GitHub.