-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
Real errors hit while building these scripts, with root causes and fixes. If you're landing here from a search for one of these error messages — welcome, you're in the right place.
Cause: There is no AdsApp.negativeKeywords() method in Google Ads Scripts. Account-level negative keywords cannot be accessed through a top-level entity iterator.
Fix: Account-level negatives live in a shared set of type ACCOUNT_LEVEL_NEGATIVE_KEYWORDS, with individual keywords stored as shared_criterion rows. Query them with GAQL:
SELECT shared_criterion.resource_name,
shared_criterion.keyword.text,
shared_criterion.keyword.match_type,
shared_set.name
FROM shared_criterion
WHERE shared_set.type = 'ACCOUNT_LEVEL_NEGATIVE_KEYWORDS'
AND shared_criterion.type = 'KEYWORD'Remove via AdsApp.mutate({ sharedCriterionOperation: { remove: resourceName } }).
Cause: A natural but wrong assumption — that account-level negative keywords live in customer_negative_criterion.keyword. That resource only carries content labels, IP blocks, mobile apps, placements, YouTube exclusions, and negative keyword list attachments. It has no keyword text fields, so GAQL rejects the query.
Fix: Same as above — query shared_criterion filtered to the ACCOUNT_LEVEL_NEGATIVE_KEYWORDS shared set type.
Cause: This isn't a bug — it's the difference between two audits. A keyword-conflict script only flags negatives that literally block a positive keyword's text. Because keywords match queries via close variants while negatives match literally, a negative can block a converting query (e.g. mens facial nyc) without conflicting with any keyword (e.g. men's facial). Apostrophes, plurals, and word additions all break literal matching.
Fix: Use the Blocked Search Term Recovery script, which audits negatives against actual search term history instead of keyword text.
Cause: AdsApp.campaigns() entity iterators do not return Performance Max campaigns, making their negatives invisible to entity-based scripts.
Fix: Query via GAQL — campaign_criterion sees all campaign types:
SELECT campaign_criterion.resource_name,
campaign_criterion.keyword.text,
campaign_criterion.keyword.match_type,
campaign.name, campaign.advertising_channel_type
FROM campaign_criterion
WHERE campaign_criterion.negative = TRUE
AND campaign_criterion.type = 'KEYWORD'
AND campaign.status = 'ENABLED'Cause: Excluded terms stop appearing in search term data from the moment they're blocked. If your LOOKBACK_DAYS window starts after the exclusions were added, there's no history to match against.
Fix: Increase LOOKBACK_DAYS (e.g. to 365) so the window reaches back before the exclusions went in.
Cause: Auto-applied recommendations. Check Recommendations → Auto-apply — if exclusion-related recommendations are enabled, Google will keep re-adding negatives.
Fix: Disable auto-apply for anything touching keywords/negatives, or schedule the recovery script weekly as a countermeasure. Also check the account's change history to identify which user or system added the exclusions.
Cause: The Google account authorizing the script doesn't have edit access to the sheet, or the URL is malformed.
Fix: Use the full URL from the browser address bar, and make sure the authorizing account can edit the sheet. The script falls back to Logger output automatically if the sheet can't be opened.
Cause: Very large accounts (hundreds of thousands of keywords or search terms).
Fix: Raise MIN_TERM_CLICKS to shrink the term set, shorten LOOKBACK_DAYS, or restrict to specific campaigns. For MCC runs, move monster accounts to their own CID-level schedule.
By AHMEEGO™ / It All Started With A Idea LLC. Stuck on something not listed? Post in r/ppc_.