Skip to content

fix(bulk-operations): chunk CS Assets bulk delete/move to the 100-item API cap (DX-9732)#297

Open
naman-contentstack wants to merge 1 commit into
v2-devfrom
fix/DX-9732
Open

fix(bulk-operations): chunk CS Assets bulk delete/move to the 100-item API cap (DX-9732)#297
naman-contentstack wants to merge 1 commit into
v2-devfrom
fix/DX-9732

Conversation

@naman-contentstack

@naman-contentstack naman-contentstack commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Problem

DX-9732: cm:stacks:bulk-assets --operation delete fails with HTTP 422 when the asset-uids file has >100 entries:

CS Assets API POST failed: status 422 ... {"errors":["Assets cannot exceed the max limit of 100."],"error_code":422}

The adapter sent the entire asset array in one POST. The CS Assets bulk delete/move endpoints cap each request at 100 items, so any bulk delete over 100 assets was completely blocked with no CLI workaround. bulkMoveAssets had the same shape.

Fix

Chunk to the cap and dispatch the batches — the publish-side QueueManager was the wrong tool (SDK/CMS-auth coupled; the delete path deliberately skips that pipeline), so this reuses the asset-management adapter's own concurrency primitives.

  • Chunking (adapter). CSAssetsAdapter.bulkDeleteAssets/bulkMoveAssets split the payload into ≤100-item batches (CS_ASSETS_BULK_MUTATE_MAX_ITEMS) via a shared dispatchBulkMutateBatches, dispatched with bounded concurrency (makeConcurrentCall) and per-batch retry (postJson({retry:true}) — 429/5xx retried, 4xx like the 422 cap not).
  • Continue on partial failure. Failed batches are collected, not rethrown (each request commits independently server-side). The aggregate result carries job_ids, notices, batchesTotal, batchesSucceeded, and failures[] ({batchIndex, count, status, error, uids}).
  • Typed errors. postJson throws CsAssetsPostError carrying the HTTP status — no error-string parsing.
  • Partial-failure UX. The runner reports what committed vs failed, writes the failed uids to a {"uids":[...]} file in the bulk-operation log folder, and prints a re-run hint (--asset-uids-file). No --retry-failed (CMS-only). Delete messaging states a submitted job is submission, not completion (delete is async).

Testing

  • contentstack-asset-management: 245 passing — adapter chunking (250→3 batches ≤100), partial-failure aggregation, failed-uid capture.
  • contentstack-bulk-operations: 831 passing — service aggregate mapping, runner partial-failure file write.
  • Verified end-to-end against a 628-uid file: 7 batches of ≤100, no 422.

🤖 Generated with Claude Code

…m API cap (DX-9732)

CS Assets bulk delete/move sent the entire asset array in one POST, so any
request over 100 items failed with HTTP 422 "Assets cannot exceed the max
limit of 100." — blocking bulk deletes of >100 assets entirely.

- CSAssetsAdapter.bulkDeleteAssets/bulkMoveAssets now split the payload into
  <=100-item batches (CS_ASSETS_BULK_MUTATE_MAX_ITEMS) dispatched with bounded
  concurrency (makeConcurrentCall) and per-batch retry (429/5xx; 4xx not retried).
- Continue-on-partial-failure: failed batches are collected, not rethrown, since
  each request commits independently. Aggregate carries job_ids, batch counts,
  and per-batch failures (with the failed uids).
- postJson throws a typed CsAssetsPostError carrying HTTP status (no error-string
  parsing).
- Runner reports partial outcomes, writes failed uids to a {"uids":[...]} file in
  the bulk-operation log folder for re-run via --asset-uids-file, and states that
  a submitted delete job is submission (not completion) since delete is async.

Tests: adapter chunking/partial-failure/uid-capture; runner partial-failure file write.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@naman-contentstack
naman-contentstack requested a review from a team as a code owner July 17, 2026 12:22
@naman-contentstack naman-contentstack self-assigned this Jul 17, 2026
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