3.1 Debugging & Snapshot Debugging in Visual Studio Code
Key Takeaways
- Interactive debugging (F5 / Attach) provides real-time execution control and breakpoint inspection but is strictly restricted to Sandbox environments and local Docker containers.
- Snapshot debugging provides an asynchronous, non-intrusive execution recorder that captures call stacks, local/global variables, and execution flow in both cloud Production and Sandbox environments without pausing user sessions or locking database records.
- Snapshot configurations in launch.json define target capture criteria such as userId, sessionId, or executionContext to isolate recording to specific user transactions.
- Snappoints (set via Shift+F9 in AL source code) act as conditional or unconditional telemetry tripwires that cause the server to log full memory and call stack states into an internal buffer when hit.
- Captured snapshot recordings are saved as .zip archive packages on the Business Central Server, downloaded to VS Code, and replayed offline via AL: Replay Snapshot Debugging (Alt+R) for post-mortem stepping and inspection.
3.1 Debugging & Snapshot Debugging in Visual Studio Code
Debugging in Microsoft Dynamics 365 Business Central is divided into two distinct paradigms: Interactive Debugging and Snapshot Debugging. Interactive debugging provides real-time, synchronous execution control (stepping, variable modification, and thread pausing) and is strictly limited to non-production environments. Snapshot debugging provides an asynchronous, non-intrusive recording mechanism engineered specifically to diagnose faults in cloud production environments without impacting active business operations.
1. Interactive Debugging Architecture & VS Code Controls
Interactive debugging attaches the Visual Studio Code debugger directly to the Business Central Server instance. When a breakpoint is reached, the server suspends the executing thread, locks the associated SQL transaction, and transfers execution control to VS Code.
Debugger Launch Configurations (launch.json)
There are two primary interactive debug request types:
"request": "launch": Deploys the current extension project to the target environment, starts a new Web Client session, and attaches the debugger immediately."request": "attach": Attaches the debugger to an existing running session or waits for the next incoming session on the server without redeploying the extension package.
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Sandbox Session",
"type": "al",
"request": "attach",
"environmentType": "Sandbox",
"environmentName": "DevelopmentSandbox",
"breakOnError": true,
"breakOnRecordWrite": false,
"enableLongRunningSqlStatements": true,
"longRunningSqlStatementThreshold": 500
}
]
}
Advanced Debugging Flags in launch.json
breakOnError: When set totrue, the debugger automatically breaks when a runtime error occurs (e.g.,Error('...')orTestFieldfailure), pausing execution at the exact line that threw the exception before the transaction rolls back.breakOnRecordWrite: Breaks whenever a database write operation occurs (Insert,Modify,Delete,ModifyAll,DeleteAll).enableLongRunningSqlStatements: Emits diagnostic debug console messages when an executed SQL statement exceeds thelongRunningSqlStatementThreshold(in milliseconds).
Breakpoint Capabilities in AL
- Standard Breakpoint (
F9): Pauses execution every time the statement is reached. - Conditional Breakpoint: Evaluates an AL expression (e.g.,
Customer."No." = '10000'orLineAmount > 5000); pauses execution only when the expression evaluates totrue. - Hit Count Breakpoint: Pauses execution after the line has executed a specified number of times (e.g.,
>= 50), invaluable for looping constructs.
VS Code Debug Inspection Panes
- Variables Pane: Displays
Globals(object-level global variables, single-instance state) andLocals(procedure parameters, local variables, andRec/xRecbuffers). - Watch Pane: Allows continuous evaluation of custom AL expressions across execution steps.
- Call Stack Pane: Displays the active procedure call hierarchy, including event publisher and subscriber invocations across different extensions.
2. Why Interactive Debugging is Blocked in Production
In Business Central SaaS production environments, interactive debugging is permanently disabled by the platform architecture for three critical reasons:
- Database Lock Escalation: Pausing an active AL thread inside an open transaction holds row and table locks in Azure SQL. If a developer pauses on a breakpoint during posting, all other users attempting to access those tables are blocked, causing severe transactional deadlocks.
- HTTP Request Timeouts: Cloud web clients and API endpoints enforce strict execution timeouts. Pausing a thread exceeds timeout thresholds, resulting in dropped sessions.
- Tenant Resource Isolation: Interactive debugging consumes disproportionate server worker threads, compromising the multi-tenant resource governance model.
3. Snapshot Debugging Architecture & Workflow
Snapshot debugging allows developers to record the execution of AL code on a production or sandbox environment. When code executes past a configured Snappoint, the server captures the call stack, source code positions, and local/global variable states into an in-memory buffer without halting the user's execution thread or holding database locks.
Required Permissions
To initialize or download a snapshot session, the user must have:
- The
D365 SNAPSHOT DEBUGpermission set assigned in Business Central. - Delegated Admin or internal user credentials with permissions to access the target environment.
launch.json Snapshot Configuration
To establish a snapshot debugging session, add a configuration entry with "request": "snapshot":
{
"name": "Capture Production Incident Snapshot",
"type": "al",
"request": "snapshot",
"environmentType": "Production",
"environmentName": "Production",
"snapshotConfiguration": {
"userId": "jane.doe@contoso.com",
"sessionId": 0,
"executionContext": "WebClient",
"captureFault": "All"
}
}
Configuration Attributes Explained
| Attribute | Type | Description |
|---|---|---|
environmentType | String | Target environment tier: Production or Sandbox. |
environmentName | String | Exact name of the Business Central cloud environment. |
userId | String | User Principal Name (UPN) or GUID of the user whose execution should be recorded. Empty or omitted attaches to any user. |
sessionId | Integer | Specific active session ID. Set to 0 to monitor any new or existing session matching the userId. |
executionContext | String | Filter execution context: WebClient, Background, WebServices, Async, or All. |
captureFault | String | All (default), None, or First. When set to First or All, automatically captures snapshot state when an unhandled runtime error occurs. |
4. End-to-End Snapshot Lifecycle: Capture, Download & Replay
The snapshot workflow follows five distinct sequential phases:
1. Initialize Snapshot ──> 2. Set Snappoints ──> 3. User Executes Scenario ──> 4. Finish Snapshot ──> 5. Replay Offline
(Alt+F5 / Palette) (F9 in Snapshot) (Live Production Work) (Alt+F5 / Palette) (Alt+R in VS Code)
Step 1: Initialize Snapshot Session
Press Alt+F5 or open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and execute AL: Initialize Snapshot Debugging. The status bar in VS Code turns orange, indicating that the server is actively listening for matching sessions.
Step 2: Set Snappoints
With the snapshot session initialized, place snappoints in your AL source files using F9 or by clicking the margin. Snappoints appear with a distinct icon. You can set:
- Standard Snappoint: Captures execution state every time execution passes through the line.
- Conditional Snappoint: Evaluates an AL condition; captures only when
true. - Log Message Snappoint: Emits formatted variable output to the snapshot log without capturing full memory dumps.
Step 3: Trigger the Scenario in Business Central
The target user (or background job) performs the business operation in the Web Client or API. As execution hits snappoints or encounters errors, the server writes execution frames to an internal snapshot archive file on the Business Central server.
Step 4: Finish and Download Snapshot
Press Alt+F5 or execute AL: Finish Snapshot Debugging. Visual Studio Code instructs the server to close the recording session. VS Code automatically downloads the resulting .zip snapshot archive into the local project's .snapshots folder (e.g., .snapshots/snapshot_20260829_103045.zip).
If multiple snapshots exist or if you need to download a previous recording, execute AL: List Snapshots to view all available server-side recordings, then select AL: Download Snapshot.
Step 5: Replay Snapshot Debugging
Open the Command Palette and select AL: Replay Snapshot Debugging (or press Alt+R), then select the downloaded .zip file from the list. VS Code launches an offline replay debug session:
- You can use standard stepping keys: Step Over (
F10), Step Into (F11), and Step Out (Shift+F11) to navigate forward and backward through the recorded execution trace. - Inspect the Variables Pane to see exact global and local variable states at every captured execution frame.
- View the full Call Stack at each snappoint.
Exam Tip: Snapshot files are standalone
.ziparchives containing the execution trace and symbol references. You do not need an active connection to the Business Central server while replaying a downloaded snapshot.
What is the primary operational difference between a standard breakpoint (F9) and a snappoint (Shift+F9) in Business Central AL development?
A developer needs to diagnose a critical calculation error occurring during sales invoice posting in a live Microsoft Dynamics 365 Business Central SaaS Production environment. Which debugging configuration must the developer use?
Which parameter in a launch.json snapshot configuration allows a developer to specifically capture execution triggered by incoming REST API requests while ignoring normal interactive Web Client users?
After finishing a snapshot debugging session on a Business Central server (Alt+F6), which step must the developer perform in Visual Studio Code to step through the recorded execution flow and inspect variable values?