Run date: 2026-04-20 (scheduled 02:30 local)
Scheduled task: google-ads-weekly-performance
Status: Blocked before any data could be pulled
Blocker category: Credentials / OAuth
This is Day 2 of the same blocker. Yesterday's Google Ads Daily Negatives — 2026-04-20 task hit the exact same invalid_grant error.
The scheduled weekly Google Ads audit could not execute because the Google Ads API OAuth refresh token stored in Notion 🔑 API Keys & App Secrets is expired/revoked. No data was pulled. No optimizations were identified. The ready-to-run audit script is built and staged; it will complete end-to-end in one run once the token is refreshed.
Error surfaced at Wed 2026-04-20 22:41:33 local when GoogleAdsClient.load_from_dict() was called with the credentials that, per the Notion 🔑 API Keys & App Secrets page, were "Verified working 2026-04-17."
Exact error from the filename-encoded flag (Desktop Commander read_file is returning only metadata this session, so diagnostic values were written into filenames and read via list_directory):
GoogleAdsClient.load_from_dict failed: RefreshError('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})
Google refresh tokens for OAuth clients in Testing publishing status expire every 7 days. Any Google Ads OAuth client that has not been moved to In production on the Google Cloud OAuth consent screen will keep hitting this approximately every week. The 2026-04-17 → 2026-04-20 gap (3 days) fits inside a 7-day window, but a revoke could also have been triggered by another client using the same refresh token slot or by a Google security sweep.
Open https://console.cloud.google.com/apis/credentials → the project that owns the Google Ads OAuth client (client_id starts with 76590338058-0imb8gdhgug9l0hqjlqacush12n0bau8).
Option A (permanent fix): Move the OAuth consent screen to In production. This removes the 7-day refresh-token expiry entirely. Requires verifying the scopes (https://www.googleapis.com/auth/adwords) and confirming it is an internal-use app.
Option B (short-term): Re-generate the refresh token via the generate_user_credentials.py helper from the google-ads-python repo. From PowerShell:
cd C:\Users\SAguiar\Documents\Projects\google-ads-python\examples\authentication
C:\Python314\python.exe generate_user_credentials.py --client_id=76590338058-0imb8gdhgug9l0hqjlqacush12n0bau8.apps.googleusercontent.com --client_secret=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
Copy the new refresh_token value from the script output.
Update Notion page 🔑 API Keys & App Secrets (page id 81b8dc90-d367-48e8-876d-085d6394e583) → Google Ads section → replace the refresh_token value. Update the # Verified working YYYY-MM-DD comment to today's date.
Re-run: C:\Python314\python.exe C:\Users\SAguiar\Documents\Projects\google-ads-weekly-2026-04-20\run_audit.py