Skip to content

Guard set_post_categories against empty-list category wipe#29

Merged
jeherve merged 1 commit into
m:mainfrom
jeherve:fix/wpcom-empty-category-wipe
Jun 3, 2026
Merged

Guard set_post_categories against empty-list category wipe#29
jeherve merged 1 commit into
m:mainfrom
jeherve:fix/wpcom-empty-category-wipe

Conversation

@jeherve

@jeherve jeherve commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

WordPress.com treats POST {categories_by_id: []} as a wipe: it strips every category off the post, and WordPress then drops the post into the site's default category. apply.md already says an empty cats list from analysis is a bug, not something to pass through. But WpcomAdapter.set_post_categories() had no guard, so a single stray empty entry would silently clear a post's categories; and since the drift check was gated on if sent_ids, the empty case skipped it, so the wipe went undetected.

Now an empty category_ids raises a ValueError unless the caller passes the new allow_clear=True (reserved for intentional clears, like restore). I documented the behavior in apply.md and added regression tests for both the refusal and the explicit-clear path.

While testing against a live Jetpack site I confirmed the guard fires: an empty list is rejected before any request goes out, so a stray empty entry can't reach WordPress.com and trigger the wipe.

Testing

  • python3 -m unittest discover tests — green
  • ruff check lib/ tests/ — clean

WordPress.com treats POST {categories_by_id: []} as a wipe: it removes
every category and reassigns the post to the site default. agents/apply.md
already documents that an empty cats list from analysis is a bug, not a
pass-through, but set_post_categories had no guard. A single empty entry
would silently strip a post's categories, and the drift check (gated on
'if sent_ids') was skipped for the empty case, so the wipe went undetected.

Refuse an empty category_ids list with a ValueError unless the caller
passes the new allow_clear=True flag (reserved for intentional clears such
as snapshot restore). Document the enforcement in apply.md and add
regression tests for both the refusal and the explicit-clear path.
@jeherve jeherve self-assigned this Jun 3, 2026
@jeherve jeherve merged commit 42714cd into m:main Jun 3, 2026
3 checks passed
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.

1 participant