# Reported issues for AdLoop

Pod holds 16 of 16 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to [AdLoop](/mcp/adloop).

## Most discussed

### discover_keywords hits RESOURCE_EXHAUSTED (429) via gRPC — REST v23 has higher quota

firstly, thank you for a great product! 

discover_keywords uses the Google Ads Python client library (gRPC transport) to call KeywordPlanIdeaService.GenerateKeywordIdeas. This quota bucket exhausts quickly — we hit it reliably with sequential single-geo calls (not parallel). The REST v23 endpoint for the same method has a higher quota and works without issue.

Steps to reproduce:
Call mcp__adloop__discover_keywords multiple times (5–10 sequential calls with different geo_target_id values).…

[Read the thread](https://github.com/kLOsk/adloop/issues/37) · 2026-05-11 · closed · external user · 4 comments

### run_ga4_report — dimensions and metrics parameters fail Pydantic validation when passed as JSON arrays

So odd but I am reporting what Claude is sharing is an issue. I have been having trouble getting to share back some data that requires `run_ga4_report`. Continues to complain about parameters. I tried with the latest version of AdLoop released today and because this is in Cowork that I experienced this, I copied to the rules shared to an AdLoop skill. So very curious if indeed this is an issue and hope I'm not just making noise here. 

---

**Tool:** `mcp__adloop__run_ga4_report`…

[Read the thread](https://github.com/kLOsk/adloop/issues/28) · 2026-04-28 · closed · external user · 4 comments

### Google App Blocked?

Hey! Awesome job

I'm tired of struggling with Google Ads terrible ux, this project what i need.

When being redirected to google for login with the wizard im getting: 

This app is blocked
This app tried to access sensitive info in your Google Account. To keep your account safe, Google blocked this access.

Is your app live?

[Read the thread](https://github.com/kLOsk/adloop/issues/17) · 2026-04-20 · closed · external user · 4 comments

### draft_responsive_search_ad does not support headline pinning (pinnedField)

When creating RSAs via draft_responsive_search_ad, all headlines are created unpinned regardless of intended position. The Google Ads API supports pinnedField (values: HEADLINE_1, HEADLINE_2, HEADLINE_3) on AdTextAsset. Please expose a pins parameter — e.g. {"H1": "HEADLINE_1", "H2": "HEADLINE_1"} — so users can define pin positions on creation without needing a manual UI step.

[Read the thread](https://github.com/kLOsk/adloop/issues/36) · 2026-05-06 · closed · external user · 3 comments

### Inquiry: Claude rules and commands

After install and init, is there something I need to do to make the Claude rules and commands available to Claude? Does not seem like they are out of the box and noticed you have a roadmap item for easier Claude install. Using this MCP in Cowork and chat currently.

[Read the thread](https://github.com/kLOsk/adloop/issues/23) · 2026-04-27 · closed · external user · 3 comments

### update_campaign: geo_target_ids array serialisation fails + no support for exclusions

## Bug 1 — Array parameter received as string

Calling `update_campaign` with `geo_target_ids` always fails with:
```
1 validation error for call[update_campaign]
geo_target_ids
  Input should be a valid list [type=list_type, input_value='["2840"]', input_type=str]
```
The MCP bridge serialises the list to a string before the tool receives it, regardless of whether values are strings or integers. The tool never receives a Python list, making `geo_target_ids` completely unusable.

## Bug 2 — No…

[Read the thread](https://github.com/kLOsk/adloop/issues/46) · 2026-06-16 · closed · external user · 2 comments

### update_ad_group: max_cpc error message misleading for automated bidding campaigns

When calling update_ad_group with max_cpc on a campaign using Maximize Clicks (TARGET_SPEND), the tool returns: "max_cpc requires an ad group in a MANUAL_CPC campaign". The refusal may be intentional — ad group CPC bids are completely ignored by Maximize Clicks per Google's own documentation (effective_cpc_bid_micros = 0, campaign ceiling is the only active constraint). But the error message implies a technical limitation rather than clarifying this. Suggested improvement: return something like…

[Read the thread](https://github.com/kLOsk/adloop/issues/31) · 2026-05-03 · closed · external user · 2 comments

### draft_campaign fails for EU accounts: missing contains_eu_political_advertising field

## Bug

`draft_campaign` → `confirm_and_apply(dry_run=false)` fails with:

```
errors {
  error_code {
    field_error: REQUIRED
  }
  message: "The required field was not present."
  location {
    field_path_elements { field_name: "mutate_operations" index: 1 }
    field_path_elements { field_name: "campaign_operation" }
    field_path_elements { field_name: "create" }
    field_path_elements { field_name: "contains_eu_political_advertising" }
  }
}
```

## Steps to reproduce

1. Configure…

[Read the thread](https://github.com/kLOsk/adloop/issues/5) · 2026-03-20 · closed · external user · 2 comments

## Most recent

### Wrong language IDs in the shipped Common Language IDs table — silently mistargets campaigns (1003/1004/1005/1009/1014)

## Summary

The **Common Language IDs** reference table in the shipped orchestration rules maps five of its eight language constants to the wrong language. Because these rules are installed into the AI assistant's context (`adloop install-rules`), an assistant that trusts the table will configure campaigns with the wrong `languageConstant` — and **Google Ads accepts it silently**. There is no error, no warning, and the campaign looks perfectly healthy in the UI.

## The table as shipped…

[Read the thread](https://github.com/kLOsk/adloop/issues/59) · 2026-08-24 · open · external user · 0 comments

### `deleted_client: The OAuth client was deleted.` — fix for AdLoop ≤0.9 (retired shared sign-in)

**If AdLoop suddenly stopped working with an error like one of these, you're in the right place:**

```
deleted_client: The OAuth client was deleted.
invalid_client: The OAuth client was not found.
RefreshError: ('deleted_client: The OAuth client was deleted.', ...)
```

## What happened

AdLoop versions **≤0.9** shipped with built-in OAuth credentials backed by a shared Google Cloud project. That project hit Google's lifetime 100-user cap for unverified apps long ago and was retired in v0.10…

[Read the thread](https://github.com/kLOsk/adloop/issues/49) · 2026-07-11 · open · 0 comments

### gaql.py: run_gaql overwrites Google's real error message and drops nested-message values (v23)

## Summary

Two reliability bugs in `src/adloop/ads/gaql.py` cause `run_gaql` (and every read tool built on `execute_query`) to surface **misleading** error messages and **drop** nested-message field values. Both were found while querying Google Ads API **v23**.

---

## Bug 1 — `_parse_gaql_error` overwrites Google's real error message with a static hint

**File:** `src/adloop/ads/gaql.py` (current `main`, around lines 65–99)

`_parse_gaql_error` matches a known code as a substring of…

[Read the thread](https://github.com/kLOsk/adloop/issues/47) · 2026-07-02 · closed · external user · 1 comment

### [Potential Vulnerability] adloop fetches a caller-controlled URL with no scheme/host validation — SSRF + local-file access via `final_url`

## Summary

`adloop` is an MCP server giving an AI assistant read/write access to Google Ads + GA4. Several of its "draft" tools accept a `final_url` (the destination URL of an ad / sitelink) and, as a convenience, **verify the URL is reachable before creating the ad**. That verification (`_validate_urls`) passes the caller-supplied URL straight to `urllib.request.urlopen()` with **no scheme allowlist and no host/IP filtering**.

Because the URL comes directly from an MCP tool argument…

[Read the thread](https://github.com/kLOsk/adloop/issues/41) · 2026-05-27 · closed · external user · 1 comment

### Bug: attach_shared_set_to_campaigns fails with partial_failure error

Tool: attach_shared_set_to_campaigns → confirm_and_apply

  Steps to reproduce

  1. Call attach_shared_set_to_campaigns with any valid shared_set_id and campaign_ids — returns plan_id successfully
  2. Call confirm_and_apply(plan_id, dry_run=false) — throws error

  Error

  CampaignSharedSetServiceClient.mutate_campaign_shared_sets() got an unexpected keyword argument 'partial_failure'

  Root cause

  The server passes partial_failure=True as a keyword argument to…

[Read the thread](https://github.com/kLOsk/adloop/issues/40) · 2026-05-25 · closed · external user · 1 comment

### update_campaign with geo_target_ids silently removes negative geo exclusions

Calling update_campaign with a geo_target_ids list replaces ALL campaign location criteria, including negative exclusions. In our case, adding a new country to positive targets silently removed a USA negative exclusion (criterion 2840, negative=True). This was only caught by running a post-change GAQL verification query. Expected behaviour: geo_target_ids should replace only positive targets, leaving negative criteria intact. Or at minimum, warn that existing negative criteria will be removed…

[Read the thread](https://github.com/kLOsk/adloop/issues/32) · 2026-05-03 · closed · external user · 1 comment

### Claude Code doesn't "know" where "Config.YAML" exists, further cannot advise "require_dry_run: false" is required to continue.

Application `Claude Code`
Operating System `Windows`
File Location: `%userprofile%/.adloop/config.yaml`

When using the ClaudeCode Configuration

Where: ` require_dry_run: true`

Claude cannot find "where" to advise user to change the configuration; Is this intentional?

```
Three plans staged. Applying with <b>dry_run=false</b>:
The server is treating the first <b>dry_run=false<b> call as a preview anyway. Re-calling to actually commit:
The AdLoop server is refusing to persist despite explicit…

[Read the thread](https://github.com/kLOsk/adloop/issues/19) · 2026-04-23 · closed · outside contributor · 1 comment

### could not locate unnable browser

There are no permissions on this repo to re-open issues, so a new issue based on existing: https://github.com/kLOsk/adloop/issues/7

_"Running on a server without a browser (VMs, Docker, SSH)? The wizard automatically detects this and falls back to a manual flow: it prints an authorization URL you can open on any device, then you paste the redirect URL back into the terminal."_
Source: https://github.com/kLOsk/adloop?tab=readme-ov-file#headless-servers

But this doesn't seem to work, I'm on a…

[Read the thread](https://github.com/kLOsk/adloop/issues/8) · 2026-04-07 · closed · external user · 1 comment

The remaining reports are on [the project's issue tracker](https://github.com/kLOsk/adloop/issues).
