15.4 AL Analyzers: CodeCop, AppSourceCop, UICop & PTECop
Key Takeaways
- Business Central provides 4 official Roslyn-based static code analyzers: CodeCop (code quality), AppSourceCop (AppSource certification & breaking changes), UICop (Web Client UI standards), and PerTenantExtensionCop (tenant extension rules).
- AppSourceCop enforces mandatory 3-to-4 character prefix/suffix rules (AS0011) and compares current code against a baseline package to prevent breaking schema changes (AS0001, AS0002).
- UICop validates Web Client behaviour, including searchable pages and reports via UsageCategory and ApplicationArea (AW0006).
- Analyzers are enabled in VS Code settings.json via al.enableCodeAnalysis and al.codeAnalyzers.
- Developers manage and customize analyzer diagnostics using ruleset.json files, which can suppress specific warnings, elevate warnings to errors, or adjust rule severities.
15.4 AL Analyzers: CodeCop, AppSourceCop, UICop & PTECop
Static code analysis is an essential phase of the Business Central software development lifecycle. Built upon the .NET Roslyn compiler framework, AL static code analyzers continuously evaluate source code to enforce coding best practices, verify UI design guidelines, detect breaking schema changes, and ensure compliance with Microsoft AppSource marketplace certification requirements.
1. The Four Official AL Static Code Analyzers
Microsoft provides four specialized code analyzers bundled directly inside the AL Language extension for Visual Studio Code and the AL compiler (alc.exe).
+-----------------------------------------------------------------------+
| AL SOURCE CODE COMPILATION |
| (.al Object Files) |
+-----------------------------------┬-----------------------------------+
│ (Roslyn Static Analysis Pipeline)
▼
+-----------------------------------------------------------------------+
| THE 4 OFFICIAL AL CODE ANALYZERS |
| |
| 1. CodeCop (${CodeCop}) |
| - General AL code quality, syntax formatting, unused variables. |
| |
| 2. AppSourceCop (${AppSourceCop}) |
| - AppSource certification, prefix/suffix, breaking changes. |
| |
| 3. UICop (${UICop}) |
| - Web Client UI standards, mandatory ToolTips, Promoted Actions. |
| |
| 4. PerTenantExtensionCop (${PerTenantExtensionCop}) |
| - Per-tenant safety, target on-prem blocks, schema validation. |
+-----------------------------------┬-----------------------------------+
│ (Filtered by ruleset.json)
▼
+-----------------------------------------------------------------------+
| COMPILER DIAGNOSTICS & BUILD GATES |
| - VS Code Problems Panel (Real-Time Squiggles & Tooltips) |
| - CI/CD Azure DevOps / GitHub Actions Automated Build Pipeline |
| - Microsoft Partner Center AppSource Technical Ingestion Gate |
+-----------------------------------------------------------------------+
1. CodeCop (${CodeCop})
- Primary Purpose: General AL code quality, styling conventions, and language best practices.
- Key Diagnostics:
AA0005: Only use BEGIN..END to enclose compound statements.AA0008: Flags function calls that omit required parentheses (e.g.,Customer.FindSetinstead ofCustomer.FindSet()).AA0137: Flags declared local or global variables that are never used in code.AA0205: Variables must be initialized before usage.AA0207: The EventSubscriber method must be local. (Variable shadowing is covered byAA0198.)
2. AppSourceCop (${AppSourceCop})
- Primary Purpose: Enforces technical rules required for publishing solutions to Microsoft AppSource, maintaining public API stability, and preventing breaking schema changes.
- Key Diagnostics:
AS0011: An affix is required — enforces the registered 3-to-4 character prefix or suffix on object names, table fields, page actions, and enum values. (AS0079extends this to procedures on extension objects;AS0013is a different rule — The field identifier must be within the allowed range.)AS0001: Tables and table extensions that have been published must not be deleted. (Pages are covered byAS0029, table renames byAS0006.)AS0002: Fields must not be deleted. (Length reductions areAS0080; length increases areAS0086.)AS0004: Fields must not change type, since dependent extensions may break. (Primary-key field changes areAS0009.)AS0018: A procedure belonging to the public API cannot be removed. (Signature changes areAS0024; return-type changes areAS0023.)
3. UICop (${UICop})
- Primary Purpose: Validates user experience and user interface standards for the modern Business Central Web Client.
- Key Diagnostics:
AW0005: Actions should use the Image property. (Missing ToolTips are a CodeCop concern —AA0218/AA0220.)AW0006: Pages and reports should use the UsageCategory and ApplicationArea properties to be searchable.AW0013: Groups containing promoted actions should not be hidden. (AW0014does the same for groups containingactionreftargets.)AW0010: A Repeater control used on a List page must be defined at the beginning of thearea(Content)section.
4. PerTenantExtensionCop (${PerTenantExtensionCop})
- Primary Purpose: Validates extensions intended exclusively for deployment as Per-Tenant Extensions (PTE) in a specific customer tenant.
- Key Diagnostics:
PTE0001: Object ID must be in free range. (The"target": "OnPrem"restriction for SaaS isPTE0005.)PTE0002: Field ID must be in free range.PTE0004: Table definitions must have a matching permission set.
2. Comprehensive Analyzer Comparison Matrix
| Analyzer Name | VS Code Identifier | Primary Scope | Mandatory For | Key Enforced Rules |
|---|---|---|---|---|
CodeCop | ${CodeCop} | Universal AL code health | All AL Projects | Unused variables (AA0137), parentheses on parameterless calls (AA0008), uninitialized variables (AA0205). |
AppSourceCop | ${AppSourceCop} | Marketplace certification & backward compatibility | AppSource ISV Apps | Registered prefix/suffix (AS0011), breaking schema change prevention (AS0001, AS0002). |
UICop | ${UICop} | Web client user experience | AppSource Apps & High-Quality PTEs | Action images (AW0005), searchable pages/reports (AW0006), hidden promoted-action groups (AW0013). |
PerTenantExtensionCop | ${PerTenantExtensionCop} | Single-tenant cloud safety | Per-Tenant Extensions (PTE) | Free-range object and field IDs (PTE0001, PTE0002), prohibits the OnPrem target (PTE0005). |
3. Enabling Analyzers in Visual Studio Code
Analyzers are enabled and configured in the project's .vscode/settings.json file. Developers can activate individual analyzers or run all four concurrently:
{
"al.enableCodeAnalysis": true,
"al.codeAnalyzers": [
"${CodeCop}",
"${AppSourceCop}",
"${UICop}",
"${PerTenantExtensionCop}"
],
"al.backgroundCodeAnalysis": "Project",
"al.ruleSetPath": "./ruleset.json",
"al.enableCodeActions": true
}
Baseline Package Configuration for AppSourceCop
To detect breaking changes between versions, AppSourceCop must compare the active workspace code against the previously published .app baseline package. This is configured in settings.json:
{
"al.assemblyProbingPaths": [
"./.netpackages"
],
"AppSourceCop.baselinePackage": "./baselines/Contoso.Logistics_23.0.0.0.app"
}
4. Managing Rules with ruleset.json
Projects can customize analyzer diagnostic behaviors using a ruleset.json file. A ruleset allows teams to elevate specific warnings to fatal compilation errors, downgrade errors to informational notices, or suppress false positives.
{
"name": "Contoso Enterprise Ruleset",
"description": "Enforces strict AppSource compliance while suppressing local casing warnings.",
"includedRuleSets": [
{
"action": "Default",
"path": "./company.ruleset.json"
}
],
"rules": [
{
"id": "AA0137",
"action": "Error",
"justification": "Unused variables must be treated as fatal compilation errors to maintain clean code."
},
{
"id": "AA0218",
"action": "Error",
"justification": "All page fields and actions must have ToolTips for user onboarding."
},
{
"id": "AA0072",
"action": "Hidden",
"justification": "Type-suffix naming is suppressed during the initial migration phase."
},
{
"id": "AS0011",
"action": "Error",
"justification": "Strict enforcement of registered publisher prefix 'CONT_'."
}
]
}
Supported Rule Actions
Error: Elevates the diagnostic to a fatal compilation error, blocking the.appbuild.Warning: Emits a warning diagnostic in the VS Code Problems panel and build logs.Info: Displays an informational tip in the IDE without failing strict warning-free builds.Hidden: Diagnostic is calculated internally by the language server but hidden from the user interface.None: Completely disables the analyzer rule calculation.
A developer needs to temporarily suppress a specific CodeCop warning (AA0137: Unused Variable) for a single procedure without modifying the project-wide ruleset.json file. Which AL preprocessor directive pattern should the developer apply?
An ISV developer is preparing an application for submission to Microsoft AppSource. Which static code analyzer is responsible for validating that all table fields, objects, and enum values include the publisher's registered 3-to-4 character prefix or suffix?
A developer runs code analysis on a new page object and receives the warning: "AW0006: Pages and reports should use the UsageCategory and ApplicationArea properties to be searchable." Which static code analyzer emitted this diagnostic?
A development team wants to configure their CI/CD build pipeline so that unused variable warnings (rule AA0137) immediately fail the build as fatal compilation errors. How should the team configure this requirement in their AL project?