bcquality/microsoft/knowledge/breaking-changes/do-not-modify-code-already-marked-obsolete.md
Jesper Schulz-Wedde 2b5550c346
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Improve partner onboarding and documentation navigation (#174)
Lead with a complete plugin quick start and add task-oriented usage, troubleshooting, customization, and contribution guides. Preserve the broader plugin framing, correct conflicting contract guidance, support Agents folder reviews, and align repository validation. Convert existing sample references to clickable links without changing knowledge rules.

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-09 17:31:03 +02:00

2 KiB

bc-version domain keywords technologies countries application-area
all
breaking-changes
obsolete
clean-flag
conditional-compilation
deprecation
replacement
do-not-extend
al
w1
all

Do not build on code already marked obsolete

Description

A member carrying [Obsolete], or wrapped in a #if not CLEANxx conditional-compilation block, is already scheduled for deletion — the CLEANxx symbol is flipped on in a future release to strip that code out. Adding logic, raising new events, or taking fresh dependencies on such a member ties live behavior to something the platform is about to remove. When the deprecation completes, everything layered on top breaks. The obsolete marker is a one-way signal: it means "migrate off," never "safe to extend." LLMs frequently edit whatever procedure is nearest to the change, including obsolete ones, and add #if not CLEANxx branches without understanding that the block is transient.

Best Practice

Leave obsolete members exactly as they are and implement against the current, supported replacement. New logic — a surcharge calculation, an event publisher, a hook — belongs on the live API (GetUnitPrice), never inside the deprecated GetPrice or behind a #if not CLEAN25 guard. If the replacement does not yet exist, create it as a first-class member and build there. The obsolete code should only shrink over time, not accrete new behavior.

See sample: do-not-modify-code-already-marked-obsolete.good.al.

Anti Pattern

Adding a surcharge calculation inside the [Obsolete] GetPrice procedure, or behind a #if not CLEAN25 block, so the new behavior is wired to code that will be removed when CLEAN25 is enabled. Detection: new statements, event declarations, or dependencies introduced inside an [Obsolete]-marked member or a #if not CLEANxx region. Move the logic onto the supported replacement instead.

See sample: do-not-modify-code-already-marked-obsolete.bad.al.