Skip to content

fix: AtlanTag propagation defaults now reach the wire (BLDX-1589) β€” breaking behavior change - #1001

Open
Aryamanz29 wants to merge 1 commit into
mainfrom
aryaman/bldx-1589
Open

fix: AtlanTag propagation defaults now reach the wire (BLDX-1589) β€” breaking behavior change#1001
Aryamanz29 wants to merge 1 commit into
mainfrom
aryaman/bldx-1589

Conversation

@Aryamanz29

Copy link
Copy Markdown
Member

Problem

AtlanTag declares propagate: Optional[bool] = Field(default=False) β€” but pyatlan serializes every request with exclude_unset=True (by design: partial updates must not stomp untouched fields). A tag built as AtlanTag(type_name=t) therefore sent no propagate on the wire, and Atlas applied its own default (CLASSIFICATION_PROPAGATION_DEFAULT = true). The SDK documented False, the server stored True.

A customer hit this in production: their webhook tags propagated via column lineage and nested-column hierarchy to columns they never tagged. (Zendesk 126980 / BLDX-1589.)

Verified live (wire captured on a test tenant):

  • AtlanTag(type_name=t) β†’ wire {"typeName": "..."} β†’ server stores propagate=True ❌
  • AtlanTag(type_name=t, propagate=False, ...) β†’ flags on the wire β†’ server preserves them βœ…

Fix

New base AtlanObjectWithDefaults: marks every field with a non-None declared default as set at construction, so exclude_unset serialization keeps it. AtlanTag extends it β€” a bare construction now sends all four propagation flags with their documented defaults:

{"typeName": "...", "propagate": false, "removePropagationsOnEntityDelete": true,
 "restrictPropagationThroughLineage": false, "restrictPropagationThroughHierarchy": false}

Verified live post-fix: server stores propagate=False for the bare construction. Fields defaulting to None/default_factory stay unset and omitted β€” nothing new leaks onto the wire. Asset models must not extend this base (docstring warns): their fields must remain omitted when untouched.

⚠️ Breaking behavior change β€” release decision needed

Callers who construct tags without propagation flags and relied (knowingly or not) on server-side propagation will stop propagating when they upgrade. This must ship with a prominent Breaking Changes release-note entry (or as v10.0.0 β€” maintainers' call). Staying on ≀9.11.0 keeps current behavior. Migration line: "if you want propagation, set propagate=True explicitly."

Not affected: tags parsed from server responses round-trip their real values (test-covered); client.asset.add_atlan_tags() already passed flags explicitly.

Audit of the same bug class

_call_api uses exclude_unset=True for all requests, so any request model with a non-None declared default is a candidate for the same lie. Swept pyatlan/model/*: candidates exist in lineage.py, group.py, keycloak_events.py, api_tokens.py, data_mesh.py β€” but each needs per-endpoint live verification (some are masked by required-field validation; some SDK defaults may match server defaults). Deliberately not batch-changed here; the new base makes each future fix a one-line inheritance change once verified. Follow-up ticket to track the audit. atlan-java likely has the same gap β€” parity check recommended.

Testing

  • 3 new unit tests: defaults reach the wire; explicit values override; server-parsed values round-trip unchanged
  • Full unit suite: 6,862 passed Β· ./qa-checks (black/flake8/mypy over 1,000 files) clean
  • Live before/after on a test tenant with wire capture (scratch tag/glossary/term, purged)

Closes BLDX-1589.

πŸ€– Generated with Claude Code

AtlanTag declared propagate=False (and three sibling flags) but pyatlan
serializes requests with exclude_unset=True, so a tag built without those
flags sent nothing β€” and the server default won (propagate=True). The
documented default was unenforceable: customers constructing
AtlanTag(type_name=t) got propagation they never asked for.

Adds AtlanObjectWithDefaults, a base that marks every field with a
non-None declared default as set at construction so exclude_unset keeps
it; AtlanTag now extends it. None/default_factory fields stay unset and
omitted β€” nothing new leaks onto the wire. Asset models must NOT extend
this base (their fields must stay omitted when untouched or partial
updates would stomp server values).

BREAKING BEHAVIOR CHANGE: callers who construct tags without propagation
flags and relied on the server default (propagate) will now get the SDK's
documented default (no propagation). Tags parsed from server responses
round-trip their real values unchanged (test-covered).

Verified live: bare AtlanTag(type_name=t) previously stored
propagate=True on the server; with this change the wire carries all four
flags and the server stores propagate=False.
@linear

linear Bot commented Aug 6, 2026

Copy link
Copy Markdown

BLDX-1589

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