{"record":{"id":"3e2f61bc6e13428d","repo":"chenhg5/cc-connect","slug":"s-stream-rich-card-text-parse-response-w","errorCode":null,"errorMessage":"%s: stream rich card text: parse response: %w","messagePattern":"(.+?): stream rich card text: parse response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platform/feishu/feishu.go","lineNumber":5246,"sourceCode":"\t}\n\n\tvar apiResp *larkcore.ApiResp\n\tif err := p.withFreshTenantAccessTokenRetry(ctx, \"stream rich card text\", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {\n\t\tvar err error\n\t\tapiResp, err = client.Put(ctx, apiPath, body, larkcore.AccessTokenTypeTenant, options...)\n\t\treturn err\n\t}); err != nil {\n\t\treturn fmt.Errorf(\"%s: stream rich card text: %w\", p.tag(), err)\n\t}\n\tif apiResp == nil || apiResp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"%s: stream rich card text: HTTP status %d\", p.tag(), apiResp.StatusCode)\n\t}\n\tvar resp struct {\n\t\tCode int    `json:\"code\"`\n\t\tMsg  string `json:\"msg\"`\n\t}\n\tif err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {\n\t\treturn fmt.Errorf(\"%s: stream rich card text: parse response: %w\", p.tag(), err)\n\t}\n\tif resp.Code != 0 {\n\t\terr := classifyFeishuCardAPIError(\"stream rich card text\", resp.Code, resp.Msg)\n\t\tif errors.Is(err, errFeishuCardRateLimited) {\n\t\t\tslog.Debug(p.tag()+\": stream rich card text rate limited; skipping frame\", \"code\", resp.Code)\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"%s: %w\", p.tag(), err)\n\t}\n\treturn nil\n}\n\n// UpdateMessage edits an existing card message identified by previewHandle.\n// Uses the Patch API (HTTP PATCH) which is required for interactive card messages.\nfunc (p *Platform) UpdateMessage(ctx context.Context, previewHandle any, content string) error {\n\tif !p.useInteractiveCard {\n\t\treturn core.ErrNotSupported\n\t}","sourceCodeStart":5228,"sourceCodeEnd":5264,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L5228-L5264","documentation":"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.","triggerScenarios":"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).","commonSituations":"Corporate proxy injecting pages; Feishu returning an undocumented envelope for this endpoint in some regions; truncated responses under heavy streaming load.","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"],"exampleFix":"// before\nif err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {\n\treturn fmt.Errorf(\"%s: stream rich card text: parse response: %w\", p.tag(), err)\n}\n// after\nif err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {\n\tslog.Warn(p.tag()+\": stream rich card text: unparseable response; continuing\", \"err\", err, \"raw\", string(apiResp.RawBody))\n\treturn nil // frames are best-effort; final Patch converges\n}","handlingStrategy":"try-catch","validationCode":"if apiResp == nil || len(apiResp.RawBody) == 0 {\n\t// skip frame; final Patch will converge\n}","typeGuard":null,"tryCatchPattern":"if err := p.StreamRichCardText(ctx, h, text); err != nil {\n\tif strings.Contains(err.Error(), \"parse response\") {\n\t\tslog.Debug(\"unparseable stream frame response; skipping frame\")\n\t\t// continue streaming\n\t}\n}","preventionTips":["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"],"tags":["feishu","cardkit","json","streaming"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}