{"record":{"id":"636dcba9e4dfab9d","repo":"chenhg5/cc-connect","slug":"googlechat-subscription-is-required-the-pub-sub","errorCode":null,"errorMessage":"googlechat: subscription is required (the Pub/Sub subscription your Chat app publishes to)","messagePattern":"googlechat: subscription is required \\(the Pub/Sub subscription your Chat app publishes to\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/googlechat/googlechat.go","lineNumber":87,"sourceCode":"\tprojectID       string // parsed from subscription, for the Pub/Sub client\n\tcredentialsFile string // service-account key, used for both receive and send\n\ttokenSource     oauth2.TokenSource\n\tallowFrom       string\n\tsessionScope    string // \"space\" (default) | \"thread\" | \"user\"\n\n\tbotClient *http.Client // service-account authed client for sending\n\tpsClient  *pubsub.Client\n\n\thandler core.MessageHandler\n\tcancel  context.CancelFunc\n}\n\n// New builds a Google Chat platform from config options.\nfunc New(opts map[string]any) (core.Platform, error) {\n\tsubscription, _ := opts[\"subscription\"].(string)\n\tsubscription = strings.TrimSpace(subscription)\n\tif subscription == \"\" {\n\t\treturn nil, fmt.Errorf(\"googlechat: subscription is required (the Pub/Sub subscription your Chat app publishes to)\")\n\t}\n\tprojectID, err := projectFromSubscription(subscription)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcredentialsFile, _ := opts[\"credentials_file\"].(string)\n\tcredentialsFile = strings.TrimSpace(credentialsFile)\n\tif credentialsFile == \"\" {\n\t\treturn nil, fmt.Errorf(\"googlechat: credentials_file is required (the Chat app's service-account key, used to pull events and send replies)\")\n\t}\n\tkeyBytes, err := os.ReadFile(credentialsFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"googlechat: read credentials_file: %w\", err)\n\t}\n\tconf, err := google.JWTConfigFromJSON(keyBytes,\n\t\tchatBotScope, \"https://www.googleapis.com/auth/pubsub\")\n\tif err != nil {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/googlechat/googlechat.go#L69-L105","documentation":"googlechat.New validates its configuration before constructing the platform. It requires the 'subscription' option: the Cloud Pub/Sub subscription that the Google Chat app publishes events to. An empty or whitespace-only value aborts construction with this message.","triggerScenarios":"Calling core.CreatePlatform(\"googlechat\", opts) (or googlechat.New directly) where opts[\"subscription\"] is absent, not a string, an empty string, or only whitespace.","commonSituations":"Missing the [platforms.googlechat] subscription entry in config.toml; key typo ('subscriptions', 'pubsub_subscription'); env-var substitution left the value empty; copying a config template without filling in the subscription resource name.","solutions":["Set subscription in the googlechat platform config to the full Pub/Sub subscription resource name, e.g. \"projects/my-project/subscriptions/chat-app-events\"","Check the config key spelling is exactly 'subscription'","Verify the value is non-empty after env expansion (echo it or run cc-connect doctor)","See TestNew_MissingSubscription for the exact accepted shape"],"exampleFix":"// before\n[[platforms]]\ntype = \"googlechat\"\n# subscription missing\n// after\n[[platforms]]\ntype = \"googlechat\"\n[platforms.options]\nsubscription = \"projects/my-project/subscriptions/chat-events\"","handlingStrategy":"validation","validationCode":"// Go: validate options before calling googlechat.New\nsub, _ := opts[\"subscription\"].(string)\nif strings.TrimSpace(sub) == \"\" {\n    return errors.New(\"googlechat: subscription must be a non-empty Pub/Sub subscription resource name\")\n}","typeGuard":null,"tryCatchPattern":"p, err := core.CreatePlatform(\"googlechat\", opts)\nif err != nil && strings.Contains(err.Error(), \"subscription is required\") {\n    return fmt.Errorf(\"config: set [platforms.options] subscription = \\\"projects/<proj>/subscriptions/<name>\\\": %w\", err)\n}","preventionTips":["Keep the full projects/<proj>/subscriptions/<name> resource name in config","Run `cc-connect doctor` at deploy time to catch empty platform options","Validate config.toml in CI before shipping","Avoid env-var indirection that can silently resolve to empty strings"],"tags":["config","googlechat","pubsub","startup"],"backgroundTag":"missing-required-config-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"}