{"record":{"id":"0c05b703e33660d8","repo":"chenhg5/cc-connect","slug":"googlechat-credentials-file-is-required-the-chat","errorCode":null,"errorMessage":"googlechat: credentials_file is required (the Chat app's service-account key, used to pull events and send replies)","messagePattern":"googlechat: credentials_file is required \\(the Chat app's service-account key, used to pull events and send replies\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/googlechat/googlechat.go","lineNumber":97,"sourceCode":"\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 {\n\t\treturn nil, fmt.Errorf(\"googlechat: parse service account credentials: %w\", err)\n\t}\n\tbotClient := conf.Client(context.Background())\n\n\tallowFrom, _ := opts[\"allow_from\"].(string)\n\n\tcore.CheckAllowFrom(\"googlechat\", allowFrom)\n\n\treturn &Platform{\n\t\tsubscription:    subscription,","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/googlechat/googlechat.go#L79-L115","documentation":"googlechat.New requires the 'credentials_file' option pointing to the Chat app's service-account JSON key, used both to pull events from Pub/Sub and to send replies via the Chat API. An empty value aborts construction with this message.","triggerScenarios":"googlechat.New invoked with opts where opts[\"credentials_file\"] is missing, not a string, empty, or whitespace-only (subscription validation has already passed).","commonSituations":"Service-account key path never added to config.toml; wrong key name ('credentials', 'service_account'); value empty because an env var is unset; migrating config from another platform that uses api_key instead.","solutions":["Set credentials_file to the absolute path of the downloaded service-account JSON key, e.g. \"/etc/cc-connect/chat-app-sa.json\"","Create/download the key from Google Cloud IAM if it doesn't exist yet (Service Accounts → Keys → Add key → JSON)","Verify the config key spelling is exactly 'credentials_file' and the value survives env expansion","Ensure the file also passes the follow-up checks (readable, valid JSON, correct scopes) to avoid the next errors"],"exampleFix":"// before\n[platforms.options]\nsubscription = \"projects/p/subscriptions/chat-events\"\n// after\n[platforms.options]\nsubscription = \"projects/p/subscriptions/chat-events\"\ncredentials_file = \"/etc/cc-connect/chat-app-sa.json\"","handlingStrategy":"validation","validationCode":"// Go: pre-validate before constructing the platform\ncred, _ := opts[\"credentials_file\"].(string)\nif strings.TrimSpace(cred) == \"\" {\n    return errors.New(\"googlechat: credentials_file must be a non-empty path to the service-account JSON key\")\n}\nif _, err := os.Stat(cred); err != nil {\n    return fmt.Errorf(\"credentials_file not readable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"p, err := core.CreatePlatform(\"googlechat\", opts)\nif err != nil && strings.Contains(err.Error(), \"credentials_file is required\") {\n    return fmt.Errorf(\"config: add credentials_file = \\\"/path/to/sa.json\\\" to googlechat options: %w\", err)\n}","preventionTips":["Always pair subscription and credentials_file in googlechat config","Verify key file presence with a startup/doctor check","Store the path in one well-documented place (e.g. /etc/cc-connect/)","Template configs with explicit placeholders so missing values are obvious"],"tags":["config","googlechat","service-account","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"}