chenhg5/cc-connect · error

googlechat: parse service account credentials: %w

Error message

googlechat: parse service account credentials: %w

What it means

After reading the key file, googlechat.New parses it via google.JWTConfigFromJSON to build a JWT config with the Chat bot and Pub/Sub scopes. If the bytes are not a valid service-account JSON key, the parse fails and construction aborts with this wrapped error.

Source

Thrown at platform/googlechat/googlechat.go:106

	}
	projectID, err := projectFromSubscription(subscription)
	if err != nil {
		return nil, err
	}

	credentialsFile, _ := opts["credentials_file"].(string)
	credentialsFile = strings.TrimSpace(credentialsFile)
	if credentialsFile == "" {
		return nil, fmt.Errorf("googlechat: credentials_file is required (the Chat app's service-account key, used to pull events and send replies)")
	}
	keyBytes, err := os.ReadFile(credentialsFile)
	if err != nil {
		return nil, fmt.Errorf("googlechat: read credentials_file: %w", err)
	}
	conf, err := google.JWTConfigFromJSON(keyBytes,
		chatBotScope, "https://www.googleapis.com/auth/pubsub")
	if err != nil {
		return nil, fmt.Errorf("googlechat: parse service account credentials: %w", err)
	}
	botClient := conf.Client(context.Background())

	allowFrom, _ := opts["allow_from"].(string)

	core.CheckAllowFrom("googlechat", allowFrom)

	return &Platform{
		subscription:    subscription,
		projectID:       projectID,
		credentialsFile: credentialsFile,
		tokenSource:     conf.TokenSource(context.Background()),
		allowFrom:       allowFrom,
		sessionScope:    normalizeSessionScope(opts["session_scope"]),
		botClient:       botClient,
	}, nil
}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Re-download a proper service-account JSON key from Google Cloud IAM (Service Accounts → Keys → Add key → JSON) and replace the file
  2. Validate the file: it must be JSON containing fields like "type": "service_account", "private_key", "client_email" (jq . < file should parse)
  3. Ensure you did not point credentials_file at an OAuth client secret or API key file
  4. Check the file wasn't truncated (file size and closing brace) after copying through secret managers

Example fix

# verify the key is a service-account key before starting
jq -e '.type == "service_account"' /etc/cc-connect/chat-app-sa.json
Defensive patterns

Strategy: validation

Validate before calling

// Go: sanity-check the key JSON before New
raw, err := os.ReadFile(path)
if err != nil { return err }
var probe map[string]any
if err := json.Unmarshal(raw, &probe); err != nil {
    return fmt.Errorf("credentials_file is not valid JSON: %w", err)
}
if t, _ := probe["type"].(string); t != "service_account" {
    return fmt.Errorf("credentials_file type is %q, want service_account", t)
}

Try / catch

p, err := core.CreatePlatform("googlechat", opts)
if err != nil && strings.Contains(err.Error(), "parse service account credentials") {
    return fmt.Errorf("credentials_file must be a service-account JSON key, not an OAuth client secret or API key: %w", err)
}

Prevention

When it happens

Trigger: googlechat.New: google.JWTConfigFromJSON(keyBytes, ...) errors because the file content is not a well-formed Google service-account JSON key — wrong file type, truncated download, OAuth client secret instead of a service-account key, or user credentials JSON.

Common situations: Downloading an OAuth client secret JSON instead of the service-account key; copying the key partially (truncated JSON); key file corrupted in transfer; accidentally pointing credentials_file at a config.toml or kubeconfig.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/fbf6761dc6b4124c. Report an issue: GitHub.