Skip to content

PROD-2316: drop unresolvable page modules instead of failing the whole page - #203

Merged
5PK merged 1 commit into
mainfrom
fix/prod-2316-drop-unresolvable-page-modules
Aug 7, 2026
Merged

PROD-2316: drop unresolvable page modules instead of failing the whole page#203
5PK merged 1 commit into
mainfrom
fix/prod-2316-drop-unresolvable-page-modules

Conversation

@5PK

@5PK 5PK commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

PROD-2316: pages referencing content the CLI couldn't resolve previously hard-failed the entire page ("No content mapping for X - content item not found in source data"), even though the per-module mapping loop had already correctly excluded the unresolvable module from the rebuilt zones. Per the team decision: the CLI should remove a page module from the target page when it can't be resolved from source data, and keep processing the page.

A module is "unresolvable" when it references a content item (item.contentid > 0) that has no source→target mapping row for the locale. The existing diagnostics classify why (content failed earlier this run / page is an unpublished draft / content in another locale only / not in source pull / model never synced) and that reason is carried into every warning.

Behavior now

  • Unresolvable modules are dropped from the pushed payload; the page pushes with everything that did resolve. Verified against the server side (BatchProcessing_BatchInsertPageItem.cs): SavePage diffs payload vs DB on ItemContainerID and ClearPageContents payload-absent modules — so a dropped module is genuinely removed from the target page, which is exactly how source-side removals/unpublishes propagate downstream. (Sending an unmapped ID instead would throw server-side and fail the whole page save, so dropping is the only viable shape.)
  • Every drop is warned, three ways: a per-module line in the structured push log, a yellow Page Module Warnings (non-blocking, N): end-of-run section with CMS links to the page and content item (same pattern as PROD-2311's mapping warnings), and warningDetails on the result objects. Warnings never affect failure counts or the exit code.
  • Self-healing: a push that dropped modules records the page mapping with sourceVersionID: 0 ("never cleanly synced"), so the page re-pushes on every sync — and re-warns — until a push completes with zero drops. Because the content phase runs before the page phase, the first sync after the underlying issue is fixed both syncs the content and restores the module onto the target page in the same run. targetVersionID is still recorded accurately, so the dirty mapping never surfaces as a false conflict.
  • Total-loss guard extended to the update path (was create-only): if every module on a page fails to resolve, the page fails rather than wiping all modules off the existing target page — that pattern signals a systemic upstream failure, not propagation. Genuine source-side emptiness (author removed all modules) is unaffected since it never produces drops.
  • All drops are collected (previously only the first missing mapping was tracked), threaded process-page → process-sitemap → push-pages → orchestrate-pushers → core/push as warningDetails.

Test plan

  • npx tsc --noEmit clean
  • npx jest — 105/105 suites, 1896/1896 tests passing; 5 new tests: partial drop pushes with correct payload + warning, dirty-mapping (sourceVersionID: 0) recorded on drop, clean push records real versionID, update-path total loss fails without calling savePage, no-content-ref modules always kept
  • Live smoke sync (832a35c9-u → 2e57774f-u) identical to pre-change baseline — same known fixture failures, exit 1, no regressions in non-page phases
  • Live page-path verification blocked on the test instance pair (page creation broken there since 2026-07-24); server-side removal semantics verified by reading BatchProcessing_BatchInsertPageItem.cs (toBeDeletedListClearPageContent)

🤖 Generated with Claude Code

…e page

A page referencing content the CLI couldn't resolve (not pulled, failed
earlier, other-locale-only, deleted) previously hard-failed in
process-page.ts even though the per-module mapping loop had already
excluded the unresolvable module from the rebuilt zones. Now the page
pushes with those modules dropped, and each drop is reported as a
non-blocking "Page Module Warnings" summary section (PROD-2311's
mapping-warnings pattern) that never affects failure counts or the exit
code.

Server-side SavePage (BatchInsertPageItem's toBeDeletedList diff) removes
payload-absent modules from an existing target page, so a dropped module
is genuinely removed on target — matching the decision that source-side
unpublished/removed modules must propagate downstream. Two safeguards:

- Self-healing: when a push drops modules, the page mapping is recorded
  with sourceVersionID 0 ("never cleanly synced"), so the page re-pushes
  on every sync until a push completes with no drops — restoring modules
  automatically once their content becomes resolvable. targetVersionID is
  still recorded accurately, so this never surfaces as a conflict.
- Total-loss guard now also covers the UPDATE path (was create-only):
  if EVERY module fails to resolve, the page fails instead of wiping all
  modules off the existing target page. Genuine source-side emptiness is
  unaffected (originalModuleCount is 0).

All drops are collected (previously only the first missing mapping was
tracked), threaded process-page → process-sitemap → push-pages →
orchestrate-pushers → core/push as warningDetails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@5PK
5PK requested a review from jules-exel August 6, 2026 19:21
@5PK
5PK merged commit cdbdd21 into main Aug 7, 2026
0 of 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.

2 participants