Error messages can be very helpful and very frustrating at the same time. The error might tell you what’s wrong, but then it just leaves you hanging instead of helping you to the solution. With BC22, we now have a way to improve that situation, check out the video:

In this video, Erik explores one of the exciting features introduced in Business Central 2023 Wave 1 (BC22): the ability to add actions to error dialogs. Instead of simply throwing an error and leaving users stuck, developers can now provide actionable next steps — either navigating users to the right page and field, or running custom code to help resolve the issue.
The Traditional Error
For decades, AL (and its predecessors) has given us a simple way to throw errors:
error('Something went wrong');
This displays a message and that’s it. The user is on their own to figure out what to do next. But starting with BC22, the Error function has an overload that accepts an ErrorInfo object, opening the door to much richer error experiences.
Introducing ErrorInfo
The ErrorInfo type lets you build a structured error with a message, and more importantly, attach actions to it. There are two types of actions you can add:
- Navigation Actions — Navigate the user to a specific page, field, and record
- Code Actions — Call a method on a codeunit to execute custom logic
Navigation Actions: Guide Users to the Right Place
A navigation action lets you point users directly to where they need to go to fix the problem. You can specify a page number, a field number (to focus the cursor on the relevant field), and a record ID to open the correct record:
e.Message := 'Not that fancy';
e.PageNo := 21; // Customer Card
e.FieldNo := Rec.FieldNo(Address);
e.RecordId := Rec.RecordId;
e.AddNavigationAction('Go North');
error(e);
When the user clicks “Go North” on the error dialog, Business Central opens the Customer Card for the specific record and focuses on the Address field. Erik demonstrated this by triggering the error while on the Alpine Ski House customer — clicking the navigation action opened the customer card for Alpine Ski House with the cursor right on the address field.
Erik also notes a nice UI improvement: Microsoft replaced the old “Click here for more details” link (which led to a mostly useless page) with a simple “Copy details” option. A small but welcome change.
Code Actions: Run Custom Logic
The second type of action calls a procedure on a codeunit. You specify a caption, a codeunit ID, and a method name:
e.AddAction('Go South', 50100, 'Behelpful');
The method must accept an ErrorInfo parameter. Here’s the full codeunit:
codeunit 50100 "Helpful"
{
SingleInstance = true;
procedure Behelpful(e: ErrorInfo)
var
C: Record Customer;
begin
C.GetBySystemId(RememberedSystemId);
message('Wasn''t that helpful? %1', C.Name);
end;
procedure SetContext(g: Guid)
begin
RememberedSystemId := g;
end;
var
RememberedSystemId: Guid;
}
The Context Problem and a Single Instance Workaround
There’s a significant limitation: the action method only receives the ErrorInfo as a parameter. You have no way to pass additional context — no dictionary, no custom parameters. After the error is thrown, a database rollback occurs, so any data you wrote during the transaction is gone.
Erik works around this by using a single instance codeunit. Since a single instance codeunit stays in memory for the duration of the session (and only one instance exists), you can store context in its global variables before throwing the error, and then retrieve that context when the action method is called:
// Before throwing the error, store context:
Helpful.SetContext(Rec.SystemId);
error(e);
// When the action fires, the context is still available in the single instance codeunit
Erik acknowledges this is “a dirty hack” and expresses hope that Microsoft will add a parameter dictionary or similar mechanism in a future version to pass context more cleanly.
The Complete Page Extension
Here’s the full page extension that ties everything together — adding a test action to the Customer Card that demonstrates both navigation and code actions:
pageextension 50100 CustomerListExt extends "Customer Card"
{
actions
{
addfirst(processing)
{
action(Test)
{
ApplicationArea = All;
Caption = 'Test';
Image = Test;
Promoted = true;
PromotedCategory = Process;
PromotedIsBig = true;
ToolTip = 'Test';
trigger OnAction()
var
e: ErrorInfo;
Helpful: Codeunit Helpful;
begin
e.Message := 'Not that fancy';
e.PageNo := 21;
e.FieldNo := Rec.FieldNo(Address);
e.RecordId := Rec.RecordId;
e.AddNavigationAction('Go North');
e.AddAction('Go South', 50100, 'Behelpful');
Helpful.SetContext(Rec.SystemId);
error(e);
end;
}
}
}
}
Bonus Experiment: Navigating to the Current Page
Erik also tested what happens when the navigation action points to the same page the user is already on. The result: Business Central opens a new instance of the Customer Card on top of the existing one. This could actually be useful — if the fix involves a field on the current screen, you could navigate users directly to that field, even if it means opening a duplicate card.
Future Possibilities
Erik shares some exciting ideas for where this could go:
- Auto-fix and retry — Imagine clicking “Post” and getting an error that posting dates are out of range. An action could extend the allowed posting date and then automatically restart the posting operation.
- Context-aware actions — With a proper parameter-passing mechanism, actions could carry enough context to perform intelligent fixes without the single instance workaround.
- Better parameter support — A dictionary or similar structure passed to the action method would eliminate the need for hacks.
Requirements
This feature requires Business Central runtime 11.0 and application version 22.0.0.0, as reflected in the app.json:
{
"application": "22.0.0.0",
"runtime": "11.0"
}
Conclusion
Actionable errors are a fantastic addition to Business Central. The core idea is powerful: when you know what went wrong, you often know how to fix it — so why not guide the user there? Navigation actions let you point users to the exact page, record, and field they need to correct. Code actions let you run logic to fix problems programmatically. The single instance codeunit workaround handles the context limitation for now, though hopefully Microsoft will provide a cleaner solution in a future release. This is a feature worth adopting in your extensions as soon as your minimum supported version allows it.