It’s that time of the year again, Microsoft has released a new version of Business Central and I fire up the old decompiler and check what’s new under the hood of the AL compiler.

In this video, Erik explores what’s new in the AL language for Business Central version 19 (2021 Wave 2) — the “Hacker Edition.” Rather than just reading release notes, Erik decompiles the language analysis DLL to discover what actually changed in the compiler, comparing runtime versions to find new attributes, functions, and deprecations.
Overview: What Microsoft Planned for v19
Erik starts by walking through Microsoft’s official “What is Planned” page for Business Central 2021 Wave 2. Here’s a summary of the key items:
- Generated documentation for AL — Microsoft commits to documenting new language features as they’re added.
- AL Profiler — A new tool (extension of the snapshot debugger) for measuring how long specific pieces of code take to run, helping identify performance bottlenecks.
- Transactional installation and sync of extensions on-premises — Multiple apps can upgrade within the same transaction, ensuring all-or-nothing upgrades via PowerShell.
- Invoice post buffer refactoring — A significant refactor of the sales posting aggregation mechanism.
- Rich access control for extension source — Replaces the old
showMyCodeboolean with a more granularresourceExposurePolicy. - System Application additions — Image module componentization and Azure Blob Service REST API.
- Change publisher/extension name — Previously, a misspelled publisher name was permanent since it was part of the primary key. Now it can be changed.
- Collectible errors in AL — The ability for code to throw and collect more than one error.
- ForceSync for customer-specific extensions in online environments — No longer need to call Microsoft support to force sync.
- Included columns in keys — A performance feature leveraging SQL Server’s included columns in indexes.
- Non-clustered columnstore indexes replacing SIFT indexes — A new way of storing aggregation data in SQL.
Resource Exposure Policy: Replacing showMyCode
One of the most visible changes in v19 is the replacement of the simple showMyCode boolean with a more granular resourceExposurePolicy in app.json. This gives developers fine-grained control over how other developers can consume their app:
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": true,
"includeSourceInSymbolFile": true
}
The three settings control:
- allowDebugging — Whether other developers can step into your code with the debugger.
- allowDownloadingSource — Whether others can download your source code (the primary functionality that
showMyCodeused to cover). - includeSourceInSymbolFile — Whether the
.alpackages downloaded as symbols include actual source code or just symbol definitions.
As Erik notes with a chuckle, “Whenever Microsoft uses the word ‘policy,’ it’s going to be heavy. I kind of liked the showMyCode yes/no — that was funky.”
Included Columns in Keys: A Performance Win
This feature is particularly exciting from a performance perspective. When SQL Server uses an index to find data, it typically needs to go back to the data file to retrieve columns that aren’t part of the index. With the new included columns support, you can tell SQL Server to store additional columns directly in the index.
This is especially powerful when combined with partial records. If your code only needs four fields, and two are already in the index, you can include the other two as included columns. SQL Server can then satisfy the entire query from the index alone — a so-called “covering index” — without ever touching the data file.
Erik emphasizes that this requires thoughtful use of partial records: “If we otherwise ask AL to get all fields anyway, then it doesn’t really matter. But in those specific scenarios where we can narrow our queries into very specific fields, this could be pretty cool.”
Non-Clustered Columnstore Indexes vs. SIFT
Another SQL-level improvement is the option to use non-clustered columnstore indexes instead of traditional SIFT indexes for calculating sum fields. The benefits include:
- Reduced logging due to eliminated SIFT index maintenance
- Faster posting performance
- Reduced storage costs
Erik highlights a particularly amusing note from Microsoft’s documentation: “Using NCCI can give you better performance, especially in situations where developers forget to add one or more SIFT indexes.” A nice safety net for common oversights.
Under the Hood: Decompiling the Compiler
Erik’s signature approach is to decompile the AL language analysis DLL and search for version compatibility tags. By searching for runtime version “8” (corresponding to Business Central v19), he can see exactly what was added or changed in the compiler.
ErrorBehavior Attribute
A new attribute called ErrorBehavior enables the collectible errors feature. You can decorate a procedure with this attribute to start collecting errors instead of throwing them immediately:
[ErrorBehavior(ErrorBehavior::Collect)]
procedure Test()
begin
// Errors thrown inside this procedure are collected
// rather than immediately stopping execution
end;
ErrorInfo Data Type
A new ErrorInfo class provides rich error information. You can create error info objects and access properties like:
- Call stack
- Whether errors are being collected
- Control name
- Custom dimensions (familiar to anyone who’s worked with telemetry)
- Data classification
- Detailed message
- Error type, field number, page number
Erik sees this as part of a broader trend: “Since Microsoft started hosting their own application, we’ve seen tremendous work on telemetry and error handling. Now they’re in our shoes — they are actually the ones getting the weird errors and having to deal with crazy scenarios.”
New System Functions for Collected Errors
Three new system functions support the collectible errors feature:
GetCollectedErrors— Retrieve all errors that were collected.ClearCollectedErrors— Clear the error collection.HasCollectedErrors— Check if any errors have been collected.
HTTP Headers Overloads
The HttpHeaders type gets new functionality:
GetValues— An overload that returns aList of [Text].GetKeys— Returns all header keys as aList of [Text].
These didn’t appear in the official release documentation, making them a genuine “hacker edition” discovery.
Variant Deprecation
A minor deprecation on the Variant type: IsDataClassificationType replaces the old IsDataTranslator — a small naming cleanup.
Wave Timing: Not Everything Ships at Once
Erik takes a moment to clarify how Microsoft’s release waves work. When Wave 2 begins and the version number increments, it doesn’t mean everything is released immediately. The wave spans six months — from October through April of the following year. Some features (like the compiler URL documentation links) were planned for December, not the initial October release.
Conclusion
While the list of changes from v18 to v19 is relatively short, Erik sees this as a positive sign of platform maturity rather than stagnation. The most impactful additions are the collectible errors system (with ErrorBehavior, ErrorInfo, and the associated system functions), the resourceExposurePolicy replacing showMyCode, and the SQL performance improvements with included columns and columnstore indexes.
From a practical upgrade perspective, unless you’re using data classification on variants, a v18 app should work in v19 after updating the showMyCode setting to the new resourceExposurePolicy in app.json — making it a straightforward upgrade path.