From cfe592fde9edc24ce9efb72b6fa7285a237657e3 Mon Sep 17 00:00:00 2001 From: Michael Dieringer <65093775+MichaelDieringer@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:06:15 +0200 Subject: [PATCH] State the four write-transaction conditions as one explicit line per method Mirrors the structure of the platform's own error message so the Report.RunModal and XmlPort.RunModal request-page exceptions are visible at a glance instead of buried in prose. Co-Authored-By: Claude Fable 5.1 --- .../runmodal-is-not-allowed-inside-write-transactions.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/microsoft/knowledge/performance/runmodal-is-not-allowed-inside-write-transactions.md b/microsoft/knowledge/performance/runmodal-is-not-allowed-inside-write-transactions.md index 5491c52..aa4b84e 100644 --- a/microsoft/knowledge/performance/runmodal-is-not-allowed-inside-write-transactions.md +++ b/microsoft/knowledge/performance/runmodal-is-not-allowed-inside-write-transactions.md @@ -11,7 +11,14 @@ application-area: [all] ## Description -Once AL code has written to the database in the current transaction — an `Insert`, `Modify`, or `Delete` with no `Commit` since — the platform refuses to open a modal object until that transaction is committed. `Page.RunModal` fails unconditionally. `Report.RunModal` and `XmlPort.RunModal` fail when they would show a request page; with it suppressed — `Report.RunModal(ReportId, false)`, where the second argument is `RequestWindow`, or `UseRequestPage(false)` on a report instance — they are allowed. `Codeunit.Run` fails when its Boolean return value is used (`if Codeunit.Run() then`), because that form commits — see `codeunit-run-requires-prior-commit-inside-transaction.md`. This is a runtime error, not a compiler diagnostic: the code builds, and the first execution that reaches the call with an open write transaction dies. The guard keys on transaction state alone, not on any relation between what was written and what is opened: an `Item.Insert()` followed by `Page.RunModal(Page::"Customer Card")` — an unrelated table — fails on the `RunModal` line, and because the error stops the transaction, the insert rolls back with it. +Once AL code has written to the database in the current transaction — an `Insert`, `Modify`, or `Delete` with no `Commit` since — the platform restricts four methods until that transaction is committed. The exact conditions, as enforced: + +- `Page.RunModal` — not allowed in a write transaction, under any circumstances. +- `Report.RunModal` — allowed only if the request page is suppressed: `Report.RunModal(ReportId, false)` (the second argument is `RequestWindow`), or `UseRequestPage(false)` on a report instance. With a request page it fails. +- `XmlPort.RunModal` — same rule: allowed only if the request page is suppressed, `XmlPort.RunModal(..., false)`. With a request page it fails. +- `Codeunit.Run` — allowed only if its Boolean return value is not used. `OK := Codeunit.Run()` and `if Codeunit.Run() then` fail, because that form commits — see `codeunit-run-requires-prior-commit-inside-transaction.md`. + +This is a runtime error, not a compiler diagnostic: the code builds, and the first execution that reaches the call with an open write transaction dies. The guard keys on transaction state alone, not on any relation between what was written and what is opened: an `Item.Insert()` followed by `Page.RunModal(Page::"Customer Card")` — an unrelated table — fails on the `RunModal` line, and because the error stops the transaction, the insert rolls back with it. The platform's message (Business Central 26, reproduced 2026-09-07) reads: "The following AL methods are limited during write transactions because one or more tables will be locked: Form.RunModal, Codeunit.Run, Report.RunModal, XmlPort.RunModal. Form.RunModal is not allowed in write transactions. Codeunit.Run is allowed in write transactions only if the return value is not used. For example, 'OK := Codeunit.Run()' is not allowed. Report.RunModal is allowed in write transactions only if 'RequestForm = false'. For example, 'Report.RunModal(...,false)' is allowed. XmlPort.RunModal is allowed in write transactions only if 'RequestForm = false'. For example, 'XmlPort.RunModal(...,false)' is allowed. Use the commit method to save the changes before this call, or structure the code differently." The message still uses the legacy names `Form.RunModal` and `RequestForm` even though the AL method is `Page.RunModal` and the report parameter is `RequestWindow`; older versions said "C/AL functions" instead of "AL methods" (microsoft/AL#5452, 2019). The behavior is unchanged across versions.