{"record":{"id":"28f7685642cf965f","repo":"chenhg5/cc-connect","slug":"s-create-card-entity-w","errorCode":null,"errorMessage":"%s: create card entity: %w","messagePattern":"(.+?): create card entity: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/feishu.go","lineNumber":5174,"sourceCode":"// (POST /open-apis/cardkit/v1/cards) and returns the card_id.\n//\n// The card_id is required to drive the streaming text update path\n// (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 == \"\" {","sourceCodeStart":5156,"sourceCodeEnd":5192,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L5156-L5192","documentation":"Wraps a transport/client error from withFreshTenantAccessTokenRetry around the POST /open-apis/cardkit/v1/cards (Create Card Entity) call. This is the %w wrap of whatever the lark SDK returned — network failure, auth failure, or retry exhaustion — and means the card entity was never created so streaming updates cannot proceed.","triggerScenarios":"The closure passed to withFreshTenantAccessTokenRetry returns a non-nil error: HTTP transport failure, token acquisition failure inside the retry helper, or context cancellation/deadline during the POST to /open-apis/cardkit/v1/cards.","commonSituations":"No network access or Feishu endpoint blocked by firewall/proxy; tenant_access_token invalid or app credentials (App ID/Secret) wrong so the fresh-token retry also fails; ctx deadline exceeded on slow networks.","solutions":["Inspect the wrapped (%v) inner error — it names the real cause (network, auth, timeout)","Verify Feishu app credentials in config.toml and that the app has cardkit permissions enabled","Check network/DNS/proxy reachability to open.feishu.cn / open.larksuite.com","Increase the context timeout for streaming sends; card creation happens on the hot message path"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := ctx.Err(); err != nil { return err } // bail before the call if already cancelled\n// ensure credentials are present:\nif appID == \"\" || appSecret == \"\" { return fmt.Errorf(\"feishu credentials missing\") }","typeGuard":null,"tryCatchPattern":"if err := p.createCardEntity(ctx, cardJSON); err != nil {\n\tvar netErr net.Error\n\tif errors.As(err, &netErr) || ctx.Err() != nil {\n\t\t// transient: fall back to inline-card-JSON send\n\t} else {\n\t\tslog.Error(\"create card entity failed\", \"err\", err)\n\t}\n}","preventionTips":["Keep app ID/secret valid and Cardkit permissions released","Set generous timeouts on the streaming send context","Monitor network reachability to open.feishu.cn from the host","Depend on the inline-card fallback so creation failure never blocks message delivery"],"tags":["feishu","cardkit","network","api-request"],"backgroundTag":"api-request-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"}