Make the logical replication conflict messages more like each other

First seen: 2026-05-18 23:08:18+00:00 · Messages: 1 · Participants: 1

Latest Update

2026-05-20 · claude-opus-4-6

Technical Analysis: Make the Logical Replication Conflict Messages More Like Each Other

Core Problem

The logical replication subsystem in PostgreSQL generates conflict messages (via conflict.c, specifically the errdetail_apply_conflict function) when the apply worker encounters situations where incoming remote changes cannot be cleanly applied to the subscriber. These conflicts are categorized into distinct types (CT_INSERT_EXISTS, CT_UPDATE_EXISTS, CT_UPDATE_DELETED, CT_UPDATE_MISSING, CT_DELETE_ORIGIN_DIFFERS, etc.), each with their own error detail messages.

The problem is one of message consistency and developer ergonomics: the current messages across these conflict types use inconsistent structure, wording, and formatting patterns. This matters because:

  1. Operational clarity: DBAs diagnosing replication conflicts need to quickly parse and understand these messages. Inconsistent formatting forces cognitive overhead when switching between different conflict types.
  2. Log parsing/monitoring: Automated tooling that parses PostgreSQL logs for replication conflicts benefits from predictable message structure.
  3. Documentation alignment: The messages should ideally mirror the documentation descriptions at logical-replication-conflicts.html.

Specific Inconsistencies Identified

Structural inconsistency

Wording inconsistency

Punctuation inconsistency

Proposed Solution

The proposal advocates for a uniform two-level message pattern across ALL conflict types:

  1. Level 1 (general): A consistent "The row to {operation} {what happened}" summary, e.g.:

    • "The row to insert violates a constraint: %s."
    • "The row to update was already deleted: %s."
    • "The row to delete was modified by another origin."
  2. Level 2 (detail): Origin/transaction specifics using "It was..." pronoun reference to avoid repetition, e.g.:

    • "It was modified locally in transaction %u at %s: %s."
    • "It was deleted by a different origin "%s" in transaction %u at %s."

Key Design Decisions in the Proposal

Implications and Tradeoffs

Positive

Concerns

Relationship to Broader Work

This proposal was originally part of another thread (referenced as [1]) working on logical replication conflict handling improvements. It was split out because the message reformatting was considered orthogonal to functional changes. This is a common pattern in PostgreSQL development — separating cosmetic/refactoring work from behavioral changes to keep patches reviewable and committable independently.

The conflict detection infrastructure in conflict.c is relatively recent (added as part of the logical replication conflict detection/resolution work in PostgreSQL 17), so cleaning up message consistency early — before more conflict types are potentially added — is strategically sound.

Current Status

This is at the RFC (Request for Comments) stage. The author explicitly states no patch will be written until there is community agreement that the direction is worthwhile. This is a sensible approach for cosmetic changes that touch many translatable strings — getting buy-in first avoids wasted effort if the community prefers the current wording or has different structural preferences.