{"record":{"id":"be3f84e5abce4baf","repo":"chenhg5/cc-connect","slug":"s-create-card-entity-empty-card-id-in-response","errorCode":null,"errorMessage":"%s: create card entity: empty card_id in response","messagePattern":"(.+?): create card entity: empty card_id in response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platform/feishu/feishu.go","lineNumber":5193,"sourceCode":"\t}\n\tif apiResp == nil || apiResp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"%s: create card entity: 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\tData struct {\n\t\t\tCardID string `json:\"card_id\"`\n\t\t} `json:\"data\"`\n\t}\n\tif err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {\n\t\treturn \"\", fmt.Errorf(\"%s: create card entity: parse response: %w\", p.tag(), err)\n\t}\n\tif resp.Code != 0 {\n\t\treturn \"\", fmt.Errorf(\"%s: %w\", p.tag(), classifyFeishuCardAPIError(\"create card entity\", resp.Code, resp.Msg))\n\t}\n\tif resp.Data.CardID == \"\" {\n\t\treturn \"\", fmt.Errorf(\"%s: create card entity: empty card_id in response\", p.tag())\n\t}\n\treturn resp.Data.CardID, nil\n}\n\n// StreamRichCardText implements core.RichCardTextStreamer. Pushes the latest\n// fullText to the rich card's main_text element via cardkit-v1 streaming text\n// update API. The Lark client renders the increment between consecutive PUTs\n// with a typewriter animation (controlled by the card's streaming_config).\n//\n// Returns ErrNotSupported when the handle has no cardID (preview was created\n// via the inline-card-JSON fallback path; engine should fall back to full-card\n// Patch).\nfunc (p *Platform) StreamRichCardText(ctx context.Context, previewHandle any, fullText string) error {\n\th, ok := previewHandle.(*feishuPreviewHandle)\n\tif !ok {\n\t\treturn fmt.Errorf(\"%s: StreamRichCardText: invalid preview handle type %T\", p.tag(), previewHandle)\n\t}\n","sourceCodeStart":5175,"sourceCodeEnd":5211,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L5175-L5211","documentation":"Cardkit returned HTTP 200, code==0 (success), but the data.card_id field is empty. The card_id is mandatory for the subsequent PUT element-content streaming calls, so a success response without it is treated as a contract violation by the API.","triggerScenarios":"POST /open-apis/cardkit/v1/cards succeeds but the JSON body omits card_id or nests it differently than the struct expects (data.card_id), e.g. an API version change or a new Cardkit entity type whose response carries the ID elsewhere.","commonSituations":"Feishu API schema drift between documented and actual response; SDK/endpoint returning an envelope where data is null on some entity types; region-specific (larksuite vs feishu) response differences.","solutions":["Log the raw response body to see where the card_id actually lives","Update the inline response struct if Feishu moved/renamed the card_id field","Upgrade the larksuite SDK / pin to the documented Cardkit v1 endpoint","Treat as fallback signal: proceed with inline-card-JSON send instead of the streaming path"],"exampleFix":"// before\nData struct {\n\tCardID string `json:\"card_id\"`\n} `json:\"data\"`\n// after\nData struct {\n\tCardID string `json:\"card_id\"`\n} `json:\"data\"`\n// plus logging on the empty path:\nif resp.Data.CardID == \"\" {\n\tslog.Warn(p.tag()+\": create card entity: empty card_id\", \"raw\", string(apiResp.RawBody))\n\treturn \"\", fmt.Errorf(\"%s: create card entity: empty card_id in response\", p.tag())\n}","handlingStrategy":"fallback","validationCode":"var probe struct{ Data struct{ CardID string `json:\"card_id\"` } `json:\"data\"` }\n_ = json.Unmarshal(apiResp.RawBody, &probe)\nif probe.Data.CardID == \"\" {\n\t// use inline-card-JSON path instead of streaming\n}","typeGuard":"func hasCardID(raw []byte) bool {\n\tvar r struct { Data struct { CardID string `json:\"card_id\"` } `json:\"data\"` }\n\treturn json.Unmarshal(raw, &r) == nil && r.Data.CardID != \"\"\n}","tryCatchPattern":"cardID, err := p.createCardEntity(ctx, cardJSON)\nif err != nil || cardID == \"\" {\n\t// engine falls back to inline-card-JSON (handle.CardID empty → ErrNotSupported from StreamRichCardText)\n}","preventionTips":["Log the raw success body when card_id is missing to catch schema drift","Watch Feishu changelog for Cardkit response changes","Always keep the non-streaming fallback enabled"],"tags":["feishu","cardkit","api-response","schema-drift"],"backgroundTag":"empty-required-field","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}