Skip to content

Sync a link to an item deleted from the source as blank - #257

Merged
5PK merged 2 commits into
mainfrom
fix/dangling-content-references
Nov 3, 2026
Merged

5PK merged 2 commits into
mainfrom
fix/dangling-content-references

Conversation

@5PK

@5PK 5PK commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Found by the gated release run for v1.3.0-beta.0 (run 41526720826). The test failed, so nothing was published.

Problem

When an item links to another item that is deleted from the source, --syncDeletes removes the target copy and its mapping. The link can then never resolve, so the unresolved-reference guard (PROD-2309) blocked the linking item for good: it couldn't be updated again, even with --overwrite. In the run, round 4 deleted one item of a reference cycle, then edited its partner on the target. The --overwrite resolve refused to push the partner with "Unresolved content reference(s) not present in the target mapping".

Fix

  • Sync (content-batch-processor.ts): a link to a content ID that has no mapping and no file in the source pull is sent blank (stripContentReferences, from the cycle work), with a warning naming the dropped link. A pull writes a file for every live item and removes deleted ones, so a missing file means the item is gone from the source. The source pull's file list is read once per processor.
    • A link to an item that exists but isn't mapped yet still fails, as before.
    • When no source content was pulled for the locale at all, nothing is treated as deleted.
    • Edge case: an unpublished source item isn't in the pull either, so a link to one is now blanked instead of failing the whole item. If the linked item is republished later, the linking item is only resent if it changes too.
  • verify (canonicalize.ts, verify-context.ts): a link to an item that no longer exists on its side (and has no mapping) drops out of the compared reference list. It now equals an empty link (what the sync sends) as well as the same kind of link on the other side.

Tests

  • content-batch-processor.test.ts:
    • a link to a gone item is blanked, with a warning (this test fails without the fix);
    • a link to an existing unmapped item still fails;
    • with no source pull, nothing is blanked.
  • check-content.test.ts: a link to a deleted target item equals an empty link (fails without the fix).
  • Full suite: 141 suites, 2,687 tests pass. tsc, ESLint and the build pass.
  • Live: a replay of the failed run (same seed 325990446, beta tier, fresh dev instances) passed every check in all 5 rounds.

After this merges, v1.3.0-beta.0 gets re-pointed at the new main commit to re-run the gated publish.

🤖 Generated with Claude Code

5PK and others added 2 commits November 2, 2026 16:53
When an item links to another that is deleted from the source (and
--syncDeletes removes its copy and mapping), the link can never resolve,
so the unresolved-reference guard (PROD-2309) blocked the linking item
for good: it could not be updated again, even with --overwrite. The v1.3.0
beta tag's live test hit it when a deleted cycle item's partner needed an
update.

A link to a content ID with no mapping and no file in the source pull
(which writes every live item and removes deleted ones) is now blanked,
using stripContentReferences, and the item is sent with a warning naming
the dropped link. A link to an item that exists but isn't mapped yet still
fails, and nothing is treated as deleted when no source content was
pulled. The source pull's file list is read once per processor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A link to an item that no longer exists on its side and has no mapping
now drops out of the compared reference list, so it equals an empty link
(the sync sends such a link blank) as well as the same kind of link on
the other side. Before, an empty link on one side and a link to a deleted
item on the other were reported as a mismatch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@5PK
5PK merged commit c59b80a into main Nov 3, 2026
3 checks passed
@5PK 5PK mentioned this pull request Nov 5, 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.

2 participants