Skip to main content

Run Codeunit / Report

Use this step to invoke any AL codeunit or processing-only report from inside a flow — your existing posting wrapper, a partner-app entry point, a batch-processing report, anything modelled as an AL object that you don't want to reimplement as a dedicated AutoFlow step.

Typical use cases:

  • Custom posting helpers. Call your existing Sales-Post (Yes/No) wrapper after a flow has prepared the document.
  • Partner-app integrations. A third-party app exposes a codeunit as its entry point — drive it from a flow without writing glue code.
  • Batch processing reports. Run a processing-only report (e.g. Calculate Plan, Suggest Vendor Payments) with saved request-page filters every night.

Configure the step

Open the flow editor, add Run Codeunit / Report, and fill in the configuration card.

Description

Specifies a meaningful description for this step. Shown in the editor and execution history. Name the operation, not the object — Post sales order reads better than Run codeunit 80.

Object type

Picks between Codeunit and Report. Default is Codeunit. Changing the type clears the Object selection so the lookup filter matches the new type.

Object

The AL codeunit or report to invoke. The lookup respects the chosen Object type. For codeunits, only Subtype = Normal is listed; a small block-list rejects codeunits whose execution from a flow would corrupt system state (see Block-list below). Reports of any kind are listed, but the step works best with processing-only reports — output from layouted reports is discarded.

Source record reference

Optional. Pass a record to the codeunit's OnRun trigger or as the report's data record. Required when the codeunit declares a TableNo, or when the report's outermost data item needs to be filtered to a single record.

Use a wrapped SmartField placeholder, e.g. {{customer}}. Press Alt+S to open the SmartField picker. The receiving codeunit or report sees a normal typed record — not a generic record reference.

Report parameters

Visible only when Object type is Report. Click the assist edit to open the report's request page and configure filters / options; close with OK and the configuration is saved. Empty means "report defaults".

If the report isn't reachable from AutoFlow's app dependencies (typically reports from localisations or vertical add-ons that AutoFlow doesn't depend on), the assist edit returns a clear error naming the report — pick a different report or have the dependency added to AutoFlow.

Edit XML

After parameters are configured, the Edit XML action opens a separate editor that lets you tweak the raw request-page parameters as XML. Use this when you want to splice SmartField placeholders into the parameters so the report runs with runtime values from the flow — for example a date filter taken from the trigger record.

Placeholders use the same {{slug.output}} syntax as the rest of the flow editor. Press Alt+S in the editor to open the SmartField picker; the chosen placeholder is copied to the clipboard so you can paste it at the cursor.

Mutual exclusivity with the request page. Once SmartField placeholders are saved into the XML, the request-page editor can't reopen the parameters — it would try to parse the placeholders as typed XML values and fail. Keep editing through Edit XML, or use Clear report parameters to start over from the request page.

Typed fields. Substituted values are inserted into the XML verbatim. Text fields are forgiving; typed fields (Date, Decimal, Boolean, Integer…) require the value to be in BC's request-page format or the report will fail with a NavType-style parse error. Use a SmartField inline format suffix ({{name;<format>}}) — ;9 is BC's XML format, which is what the request-page parser expects:

<Field name="StartDate">{{trigger.postingDate;9}}</Field>

That emits 2026-05-26 for a Date, 1234.56 for a Decimal, true/false for a Boolean — formats the request-page parser accepts in any locale. The same ;9 suffix applies across all typed values.

If a substituted value can contain &, < or >, XML-escape it yourself (&amp;, &lt;, &gt;).

Behavior

The step invokes the codeunit or report; passes the resolved record if you configured one. The boolean success output is set when the call returns cleanly. If the codeunit or report raises an error, the step fails with the underlying message (Codeunit 80 failed: Posting Date X is not within your range of allowed posting dates, etc.) and the flow follows its normal error-handling path.

The target object runs in its own transaction, independent of the flow. That means anything it writes — a posted document, an updated record, an entry — is committed regardless of what later flow steps do. The flow can't roll back the target's work by failing afterwards. Design flows so a successful invocation is a meaningful commit boundary.

Outputs

OutputTypeDescription
successValue (Boolean)Set to true after a successful invocation. Failures stop the step with an Error, so there's no false value to branch on.

Block-list

A small set of standard Business Central codeunits is rejected, at configure time and at runtime. Reports aren't block-listed.

CodeunitWhy blocked
1 – ApplicationManagementLegacy system-bootstrap hook; re-running corrupts startup state.
2 – Company-InitializeRewrites all standard configuration tables; one run leaves a live company inconsistent.
40 – LogInManagementDrives the login pipeline; running it outside the login context corrupts session state.
357 – DateComprRegisterDate compression — irreversible data destruction.
358 – DateComprMgtDate compression — irreversible data destruction.

Codeunits with Subtype = Test, Install, or Upgrade are also rejected — their lifecycles assume a single framework-managed invocation.

Best practices

  • Prefer processing-only reports for batch work. Reports with a layout (PDF / Word / Excel) generate output this step discards. Use the Create PDF Document step if you want a file.
  • Keep heavy objects out of tight loops. Some legitimate codeunits and reports — Adjust Cost - Item Entries, Date Compression, Calculate Plan — do a lot of I/O and hold long table locks. Don't call them from a For Each Loop over thousands of rows; batch upstream first.
  • Don't disguise data destruction as flow logic. If the effect is "delete a lot of rows," prefer the typed Delete Record step (which writes audit entries to the execution log) over running a custom cleanup codeunit.