Skip to content

Conversation

@bokelley
Copy link
Contributor

Problem

The targeting values endpoint (/admin/api/tenant/{tenant_id}/targeting/values/{key_id}) was returning 500 errors for tenants using service account authentication (like the Weather Company tenant).

Root Cause

In PR #723, we added service account authentication support to this endpoint. However, we were passing raw google.oauth2.service_account.Credentials directly to ad_manager.AdManagerClient().

The googleads library requires credentials to be wrapped in oauth2.GoogleCredentialsClient to provide the CreateHttpHeader() method that the GAM API client expects.

Error:

AttributeError: 'Credentials' object has no attribute 'CreateHttpHeader'

Solution

Added the oauth2.GoogleCredentialsClient(credentials) wrapper, matching the pattern used in:

  • src/services/background_sync_service.py (line 214)
  • src/adapters/gam/auth.py (lines 100, 111)
  • src/adapters/gam/utils/health_check.py (line 86)
  • src/admin/blueprints/gam.py (line 878)

Testing

Verified the fix works by:

  1. Confirming Weather tenant has service account configured: ✅
  2. Testing the exact error path in production SSH console: ✅
  3. Confirming the fix resolves the CreateHttpHeader() error: ✅

Impact

🤖 Generated with Claude Code

The targeting values endpoint was failing with 500 error for tenants using
service account authentication because we were passing raw
google.oauth2.service_account.Credentials directly to AdManagerClient.

The googleads library requires credentials to be wrapped in oauth2.GoogleCredentialsClient
to provide the CreateHttpHeader() method that the GAM API client expects.

Error:
  AttributeError: 'Credentials' object has no attribute 'CreateHttpHeader'

Fix:
  Add oauth2.GoogleCredentialsClient(credentials) wrapper, matching the pattern
  used in:
  - src/services/background_sync_service.py
  - src/adapters/gam/auth.py
  - src/adapters/gam/utils/health_check.py
  - src/admin/blueprints/gam.py

This was missed in PR #723 which added service account support to this endpoint.

Fixes: https://sales-agent.scope3.com/admin/api/tenant/weather/targeting/values/289457

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley bokelley merged commit 9d21709 into main Nov 11, 2025
9 checks passed
danf-newton pushed a commit to Newton-Research-Inc/salesagent that referenced this pull request Nov 24, 2025
…dcontextprotocol#727)

The targeting values endpoint was failing with 500 error for tenants using
service account authentication because we were passing raw
google.oauth2.service_account.Credentials directly to AdManagerClient.

The googleads library requires credentials to be wrapped in oauth2.GoogleCredentialsClient
to provide the CreateHttpHeader() method that the GAM API client expects.

Error:
  AttributeError: 'Credentials' object has no attribute 'CreateHttpHeader'

Fix:
  Add oauth2.GoogleCredentialsClient(credentials) wrapper, matching the pattern
  used in:
  - src/services/background_sync_service.py
  - src/adapters/gam/auth.py
  - src/adapters/gam/utils/health_check.py
  - src/admin/blueprints/gam.py

This was missed in PR adcontextprotocol#723 which added service account support to this endpoint.

Fixes: https://sales-agent.scope3.com/admin/api/tenant/weather/targeting/values/289457

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants