{"record":{"id":"47da768cba0ba985","repo":"chenhg5/cc-connect","slug":"s-create-card-entity-http-status-d","errorCode":null,"errorMessage":"%s: create card entity: HTTP status %d","messagePattern":"(.+?): create card entity: HTTP status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/feishu.go","lineNumber":5177,"sourceCode":"// (PUT /open-apis/cardkit/v1/cards/{card_id}/elements/{element_id}/content).\n// If this call fails the caller should fall back to inline card JSON via the\n// regular Im.Message.Create path; the rich card will still render but without\n// native typewriter streaming.\nfunc (p *Platform) createCardEntity(ctx context.Context, cardJSON string) (string, error) {\n\tbody := map[string]any{\n\t\t\"type\": \"card_json\",\n\t\t\"data\": cardJSON,\n\t}\n\tvar apiResp *larkcore.ApiResp\n\tif err := p.withFreshTenantAccessTokenRetry(ctx, \"create card entity\", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {\n\t\tvar err error\n\t\tapiResp, err = client.Post(ctx, \"/open-apis/cardkit/v1/cards\", body, larkcore.AccessTokenTypeTenant, options...)\n\t\treturn err\n\t}); err != nil {\n\t\treturn \"\", fmt.Errorf(\"%s: create card entity: %w\", p.tag(), err)\n\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","sourceCodeStart":5159,"sourceCodeEnd":5195,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L5159-L5195","documentation":"The cardkit Create Card Entity API completed at the transport level but returned a non-200 HTTP status (or a nil response). The code checks apiResp.StatusCode != http.StatusOK before parsing the body, so gateway errors, auth rejections (401/403), and rate-limit responses surface here rather than as a Lark business code.","triggerScenarios":"POST /open-apis/cardkit/v1/cards returns 4xx/5xx: invalid or expired tenant_access_token (401), missing cardkit card scope (403), card JSON too large (413), Feishu server error (5xx), or a proxy returning 502/504. Also fires when apiResp is nil despite a nil error from the client.","commonSituations":"App not granted Cardkit (Card Entity) permission in the Feishu developer console; token refresh raced and an expired token was used; very large streaming card JSON exceeding body limits; corporate proxy intercepting the call.","solutions":["Read the logged status code: 401/403 → fix app credentials or grant cardkit:card permission in the Feishu developer console; 5xx → retry later","Confirm the app version containing the Cardkit permission is published/released (permissions must be released, not just enabled)","Reduce the card JSON size (trim schema/whitespace) if 413","Check proxy/firewall interference if statuses like 502 appear"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// pre-flight: verify a cheap cardkit call works at startup\n// e.g. doctor check that POST /open-apis/cardkit/v1/cards is authorized","typeGuard":null,"tryCatchPattern":"if err != nil {\n\tvar httpErr *HTTPStatusError // or match on the wrapped message\n\tif errors.As(err, &httpErr) && httpErr.Status == 403 {\n\t\t// disable streaming path; use inline-card JSON permanently\n\t}\n}","preventionTips":["Grant and RELEASE cardkit permissions in the Feishu developer console","Keep tokens fresh — the code already retries with a fresh tenant token","Keep card JSON small to avoid 413","Alert on sustained 5xx from Feishu endpoints"],"tags":["feishu","cardkit","http","permissions"],"backgroundTag":"http-non-2xx-response","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"}