bcquality/microsoft/knowledge/appsource/object-affixes-prevent-collisions.md
Jesper Schulz-Wedde 186d8a1314
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
Complete AL review knowledge readiness (#108)
* Complete AL review knowledge readiness

Fill telemetry and Query coverage, strengthen thin review domains, correct audited content defects, and add deterministic cheap-model evaluation and reference-integrity safeguards.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Generalize review fixture discovery

Derive smoke cases from the leaf, domain, and paired-sample conventions so new leaves require no scoring-contract changes. Keep only exceptional selection/context overrides and fail when retrieval metadata cannot rank the selected article.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Preserve published field IDs in sample

Keep the existing Email and Contact Email field IDs unchanged, clarify that the sample represents an independent baseline, and use a local breaking-change rule for the generic smoke evaluation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Clarify published field identity rules

State explicitly that a published field keeps its ID, name, and type while a replacement is added as a separate field under an unused ID.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Align field obsoletion sample baselines

Use Email field ID 3 as the shared baseline so the bad example demonstrates a same-ID rename while the good example retains the original field and adds a separate replacement.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
2026-07-15 10:55:25 +02:00

2 KiB

bc-version domain keywords technologies countries application-area
all
appsource
object-affix
prefix
suffix
as0011
appsourcecop
collision
tableextension
al
w1
all

Apply a reserved affix to objects and to members added to base objects

Description

An AppSource extension must prevent name collisions through its registered affix or, on BC23 and later for objects it owns, a namespace with at least two levels. The affix still applies to every field, key, control, or action added to a base-application object; see two-level-namespace-replaces-object-affix-not-extension-member-affix.md. Without either mechanism, two apps that both define a Loyalty Tier table cannot coexist, and two apps that add an unaffixed Loyalty Points field to Customer still collide regardless of their namespaces.

AppSourceCop enforces this. The primary rule is AS0011 ("An affix is required"); the affixes are configured through mandatoryAffixes (and mandatoryPrefix) in AppSourceCop.json. Two placements matter and are easy to get half-right: an object you define carries the affix at object-name level, while a member you add to a standard object carries the affix on that member's name. Adding an affixed object is not enough — an unaffixed field bolted onto Customer still collides and still fails validation.

Best Practice

Own objects use the registered affix (for example ABC Loyalty Tier) or, when targeting BC23 or later, a qualifying namespace. Every field or action added to a standard object remains individually affixed (for example Loyalty Points ABC on a Customer tableextension).

See sample: object-affixes-prevent-collisions.good.al.

Anti Pattern

An owned object with neither a qualifying namespace nor an affix, an unaffixed extension member, or the common half-measure where the extension object carries the affix but a field it adds to a standard table does not. AS0011 flags the missing collision protection and the field can still collide with another app.

See sample: object-affixes-prevent-collisions.bad.al.