You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[docs] Clarify expression purity, fail-loudly argument contracts, and server-side transactional authority for client-side functions #4162
Client-side functions in a2ui_core are a major architectural win—compiling deterministic local Dart functions directly into synchronous preact_signalscomputed() nodes removes both LLM round-trip latency and async widget glue.
However, as teams adopt this pattern in production Flutter applications, three recurring questions come up immediately in engineering reviews. Documenting these explicitly in the official GenUI / A2UI guides and sample code will prevent common anti-patterns before they ship.
Three Areas to Document
1. Expression Purity vs. Action Side Effects (execute() Synchronicity)
Because FunctionImplementation.execute() runs synchronously inside the reactive signal graph, docs should explicitly call out the physical boundary:
Safe in execute() (UI Expression Bindings): Pure, deterministic math, formatting, and synchronous reads against pre-warmed in-memory state (O(1) lookups).
Unsafe in execute(): Disk I/O (SQLite), network calls, async platform channels, or state mutations. Async lookups and side effects belong in explicit user actions (SubmitAction) or out-of-band repository updates that populate the DataModel / in-memory cache cleanly.
2. Fail Loudly on Broken Contracts (Avoid ?? 0.0 in Samples)
When an example FunctionImplementation handles missing required arguments using silent defaults like (args['unitPrice'] as num?)?.toDouble() ?? 0.0, developers copy that pattern into pricing or eligibility logic. If a DataModel path is misspelled, the UI silently displays $0.00.
Recommendation: Recommend asserting/throwing ArgumentError on missing required parameters inside execute() so UI error boundaries catch broken paths rather than displaying plausible-looking wrong numbers.
3. Optimistic Client Ergonomics vs. Authoritative Server Validation
Examples featuring client-side discount or pricing functions (such as applying a 20% promo code locally) immediately trigger a valid security concern: "What stops a tampered client from applying that discount repeatedly?"
Recommendation: Clarify in the GenUI security guidance that client-side functions provide optimistic, 120 FPS interactive previews, while final transactional authority (checkout totals, coupon eligibility, inventory) always remains server-side on action submission.
Summary:
The issue asks for docs on client-side functions in a2ui_core: keep FunctionImplementation.execute() free of I/O and side effects, throw on missing required arguments instead of defaulting them (as in ?? 0.0), and state that the server, not the client, decides final prices and discounts.
Why flagged for triage:
This issue has external input but no priority label yet.
Suggestion:
Set P3: the advice is reasonable, but the issue reports no defect, and docs on this are not on the roadmap. Two of its premises are partly off. I found no ?? 0.0 default in the repository's samples or docs, so the pattern it warns about does not come from this repository. And execute() can return a ReadonlySignal and takes a CancellationSignal, so a function can deliver its result later, which a "synchronous only" rule would have to account for. The third point is partly covered already: Agent functions describes server-side operations such as validating a coupon code. #4161, by the same author, asks how a2ui_core should handle unresolved required arguments, the code side of the second point. #4163, also by the same author, asks for related catalog design docs.
<a2ui>
root = TriageSuggestion(
summary="""The issue asks for docs on client-side functions in `a2ui_core`: keep `FunctionImplementation.execute()` free of I/O and side effects, throw on missing required arguments instead of defaulting them (as in `?? 0.0`), and state that the server, not the client, decides final prices and discounts.""",
reason="This issue has external input but no priority label yet.",
suggestion="""Set P3: the advice is reasonable, but the issue reports no defect, and docs on this are not on the [roadmap](https://github.com/a2ui-project/a2ui/blob/8bf644a37d680a227296b8c0849a7f4b328b8b73/docs/public/roadmap.md). Two of its premises are partly off. I found no `?? 0.0` default in the repository's samples or docs, so the pattern it warns about does not come from this repository. And [`execute()`](https://github.com/a2ui-project/a2ui/blob/8bf644a37d680a227296b8c0849a7f4b328b8b73/dart/a2ui_core/lib/src/core/catalog.dart#L217-L222) can return a `ReadonlySignal` and takes a `CancellationSignal`, so a function can deliver its result later, which a "synchronous only" rule would have to account for. The third point is partly covered already: [Agent functions](https://github.com/a2ui-project/a2ui/blob/8bf644a37d680a227296b8c0849a7f4b328b8b73/docs/site/src/content/docs/concepts/actions-and-functions.mdx?plain=1#L173-L181) describes server-side operations such as validating a coupon code. #4161, by the same author, asks how `a2ui_core` should handle unresolved required arguments, the code side of the second point. #4163, also by the same author, asks for related catalog design docs.""",
added_labels=["type: feature/enhancement", "P3", "component: documentation", "lang: dart"],
related_issues=[4161, 4163]
)
</a2ui>
Hi @RandalSchwartz, Thank you for raising the issue. We appreciate you taking the time to share your thoughts with us.
Hi @gspencergoog, could you please take a look?
Activity
polina-c commentedon Nov 12, 2026
From triage bot:
Triage suggestion:
For humans
Summary:
The issue asks for docs on client-side functions in
a2ui_core: keepFunctionImplementation.execute()free of I/O and side effects, throw on missing required arguments instead of defaulting them (as in?? 0.0), and state that the server, not the client, decides final prices and discounts.Why flagged for triage:
This issue has external input but no priority label yet.
Suggestion:
Set P3: the advice is reasonable, but the issue reports no defect, and docs on this are not on the roadmap. Two of its premises are partly off. I found no
?? 0.0default in the repository's samples or docs, so the pattern it warns about does not come from this repository. Andexecute()can return aReadonlySignaland takes aCancellationSignal, so a function can deliver its result later, which a "synchronous only" rule would have to account for. The third point is partly covered already: Agent functions describes server-side operations such as validating a coupon code. #4161, by the same author, asks howa2ui_coreshould handle unresolved required arguments, the code side of the second point. #4163, also by the same author, asks for related catalog design docs.type: feature/enhancement,P3,component: documentation,lang: dartTo adjust and apply this suggestion, run in your a2ui checkout:
For software
🤖 Agent-generated
Varun-S10 commentedon Nov 12, 2026
Hi @RandalSchwartz, Thank you for raising the issue. We appreciate you taking the time to share your thoughts with us.
Hi @gspencergoog, could you please take a look?