Split out from #555 as the P2 scope (mutation batch limits), so the P0 array-length preflight (#555 PR) could ship verified-live without bundling unverified mutation caps.
Scope
Add preflight size/empty-ID checks to mutating commands that currently forward arrays / single IDs to the API with no size or empty-ID validation:
keywords update
ads add / ads update
adgroups add / adgroups update
- the lifecycle commands built by
direct_cli/commands/_lifecycle.py
Why separate from P0
The P0 array-length limits on get (keywordbids/dynamicads/smartadtargets) were measured live against the v5 API (#555 PR — merged). The mutation batch limits here are not yet verified live and need their own measurement pass (bump each batch by one past the suspected ceiling, read the exact 4001/per-item error, pin a constant with a doc/live citation — same discipline as KEYWORDS_ADD_MAX_BATCH and the new *_GET_CRITERIA_LIMITS constants).
Not in scope
Approach
Reuse direct_cli/utils.py::enforce_criteria_array_limits (added in the #555 P0 PR) where the mutation also builds a SelectionCriteria, and follow the keywords.py _warn_on_adgroup_overflow / _chunked precedent for true batch endpoints. TDD + live verification per command.
Refs #555
Split out from #555 as the P2 scope (mutation batch limits), so the P0 array-length preflight (#555 PR) could ship verified-live without bundling unverified mutation caps.
Scope
Add preflight size/empty-ID checks to mutating commands that currently forward arrays / single IDs to the API with no size or empty-ID validation:
keywords updateads add/ads updateadgroups add/adgroups updatedirect_cli/commands/_lifecycle.pyWhy separate from P0
The P0 array-length limits on
get(keywordbids/dynamicads/smartadtargets) were measured live against the v5 API (#555 PR — merged). The mutation batch limits here are not yet verified live and need their own measurement pass (bump each batch by one past the suspected ceiling, read the exact 4001/per-item error, pin a constant with a doc/live citation — same discipline asKEYWORDS_ADD_MAX_BATCHand the new*_GET_CRITERIA_LIMITSconstants).Not in scope
getempty-SelectionCriteria guards forcampaigns/adextensions(Add preflight validation for SelectionCriteria array sizes (and other uncovered limits) #555 P1) — won't fix: the live API accepts an empty{}for those and returns data, so a guard would remove working whole-account paging.Approach
Reuse
direct_cli/utils.py::enforce_criteria_array_limits(added in the #555 P0 PR) where the mutation also builds a SelectionCriteria, and follow thekeywords.py_warn_on_adgroup_overflow/_chunkedprecedent for true batch endpoints. TDD + live verification per command.Refs #555