{"record":{"id":"0d9e1074e2613785","repo":"chenhg5/cc-connect","slug":"googlechat-create-pubsub-client-w","errorCode":null,"errorMessage":"googlechat: create pubsub client: %w","messagePattern":"googlechat: create pubsub client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/googlechat/googlechat.go","lineNumber":163,"sourceCode":"\t\treturn \"space\"\n\tdefault:\n\t\tslog.Warn(\"googlechat: unknown session_scope, using \\\"space\\\"\", \"value\", s)\n\t\treturn \"space\"\n\t}\n}\n\nfunc (p *Platform) Name() string { return \"googlechat\" }\n\nfunc (p *Platform) Start(handler core.MessageHandler) error {\n\tp.handler = handler\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tp.cancel = cancel\n\n\tclient, err := pubsub.NewClient(ctx, p.projectID, option.WithTokenSource(p.tokenSource))\n\tif err != nil {\n\t\tcancel()\n\t\treturn fmt.Errorf(\"googlechat: create pubsub client: %w\", err)\n\t}\n\tp.psClient = client\n\n\tgo p.receiveLoop(ctx)\n\tslog.Info(\"googlechat: started\", \"subscription\", p.subscription, \"scope\", p.sessionScope)\n\treturn nil\n}\n\n// receiveLoop runs a streaming pull on the subscription, restarting with a small\n// backoff if Receive returns an error while the context is still alive.\nfunc (p *Platform) receiveLoop(ctx context.Context) {\n\tconst backoff = 5 * time.Second\n\tsub := p.psClient.Subscriber(p.subscription)\n\tfor {\n\t\tif ctx.Err() != nil {\n\t\t\treturn\n\t\t}\n\t\terr := sub.Receive(ctx, func(_ context.Context, m *pubsub.Message) {","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/googlechat/googlechat.go#L145-L181","documentation":"Start creates the Pub/Sub client used to receive Google Chat events, authenticating with the configured token source. When pubsub.NewClient fails (auth error, network error, bad project ID, missing Pub/Sub API), Start cancels its context and returns this wrapped error so the platform fails to start cleanly.","triggerScenarios":"Calling Start on a googlechat Platform whose projectID is wrong, whose tokenSource credentials lack Pub/Sub permissions or are expired/invalid, when the Pub/Sub API is not enabled for the project, or when network/DNS to Google endpoints fails.","commonSituations":"Pub/Sub API not enabled in the GCP console; service account missing roles/pubsub.subscriber; GOOGLE_APPLICATION_CREDENTIALS misconfigured or stale key file; typos in the project ID; corporate firewall blocking googleapis.com.","solutions":["Enable the Cloud Pub/Sub API: `gcloud services enable pubsub.googleapis.com --project <project>`","Grant the service account roles/pubsub.subscriber on the subscription and verify the token source credentials are valid and unexpired","Confirm the project ID matches the project in the subscription resource name and that the network can reach pubsub.googleapis.com:443"],"exampleFix":"// before\ncc-connect start  # fails: googlechat: create pubsub client: rpc error: ... permission denied\n// after\ngcloud services enable pubsub.googleapis.com\ngcloud pubsub subscriptions add-iam-policy-binding projects/P/subscriptions/S --member=serviceAccount:bot@P.iam.gserviceaccount.com --role=roles/pubsub.subscriber","handlingStrategy":"try-catch","validationCode":"// preflight: verify API + IAM before Start\nout, err := exec.Command(\"gcloud\", \"pubsub\", \"subscriptions\", \"describe\", sub, \"--format=value(name)\").Output()","typeGuard":null,"tryCatchPattern":"if err := platform.Start(ctx); err != nil {\n    var pe *googleapi.Error\n    if errors.As(err, &pe) {\n        slog.Error(\"pubsub client failed\", \"code\", pe.Code, \"body\", pe.Body)\n    }\n    return fmt.Errorf(\"googlechat start: %w\", err)\n}","preventionTips":["Enable the Pub/Sub API and grant roles/pubsub.subscriber to the bot's service account during provisioning","Run a doctor/preflight check that creates (and closes) a pubsub client before daemon start","Keep service-account key files rotated and confirm GOOGLE_APPLICATION_CREDENTIALS points at a live file"],"tags":["googlechat","gcp","pubsub","network","auth"],"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"}