{"record":{"id":"e7b4ba954dcf34fa","repo":"chenhg5/cc-connect","slug":"s-client-not-initialized","errorCode":null,"errorMessage":"%s: client not initialized","messagePattern":"(.+?): client not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/feishu.go","lineNumber":1131,"sourceCode":"\tfor _, needle := range []string{\"withdrawn\", \"recalled\", \"recall\", \"deleted\", \"not found\", \"not exist\", \"撤回\"} {\n\t\tif strings.Contains(msg, needle) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *Platform) IsMessageRecalled(ctx context.Context, rctx any) (bool, error) {\n\trc, ok := rctx.(replyContext)\n\tif !ok || strings.TrimSpace(rc.messageID) == \"\" {\n\t\treturn false, nil\n\t}\n\tmessageID := strings.TrimSpace(rc.messageID)\n\tif p.isMessageRecalled(messageID) {\n\t\treturn true, nil\n\t}\n\tif p.client == nil {\n\t\treturn false, fmt.Errorf(\"%s: client not initialized\", p.tag())\n\t}\n\n\treq := larkim.NewGetMessageReqBuilder().\n\t\tMessageId(messageID).\n\t\tUserIdType(larkim.UserIdTypeGetMessageOpenId).\n\t\tBuild()\n\n\tvar resp *larkim.GetMessageResp\n\tif err := p.withTransientRetry(ctx, \"get message\", func() error {\n\t\treturn p.withFreshTenantAccessTokenRetry(ctx, \"get message\", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {\n\t\t\tvar err error\n\t\t\tresp, err = client.Im.Message.Get(ctx, req, options...)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s: get message api call: %w\", p.tag(), err)\n\t\t\t}\n\t\t\tif !resp.Success() {\n\t\t\t\treturn fmt.Errorf(\"%s: get message failed code=%d msg=%s\", p.tag(), resp.Code, resp.Msg)\n\t\t\t}","sourceCodeStart":1113,"sourceCodeEnd":1149,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L1113-L1149","documentation":"A recall-check lookup needs the Lark API client, but p.client is nil — the platform's client was never initialized. This is an internal invariant violation: the platform should have created its client in newPlatform/Start before handling messages.","triggerScenarios":"Invoking the message-recall check (isMessageRecalled path) before Start() initializes the client, or after a failed initialization, on a message containing a resource reference.","commonSituations":"Partial startup failure (credential error swallowed elsewhere); calling platform methods directly in tests without a started platform; race between message delivery and platform initialization.","solutions":["Ensure the platform started successfully (check startup logs for earlier init errors) before messages flow.","Verify app_id/app_secret are valid so client construction doesn't fail silently.","Restart cc-connect; if reproducible, report as a bug — this indicates a startup-order defect."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":"func (p *Platform) clientReady() bool { return p.client != nil }","tryCatchPattern":"if !p.clientReady() {\n    // degrade: assume not recalled instead of failing the message flow\n    return false, nil\n}","preventionTips":["Never deliver messages to platform methods before Start() completes.","Check startup logs for earlier client-init failures.","Guard test harnesses with an explicit client stub."],"tags":["feishu","initialization","invariant-violation"],"backgroundTag":"internal-invariant-violation","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"}