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
Split out of #2896, which is closed — the fix there was to stop mislabeling a server-side body ("No script provided for script action" → an error naming the real cause). This is the follow-up that #2896 explicitly deferred, filed so it is not buried in a closed issue.
ActionSchema.body (HookBodySchema — L1 expression / L2 sandboxed JS) is the spec's preferred binding for script actions. Bodies execute server-side, via POST /api/v1/actions/{object}/{action} → the runtime sandbox.
In the console this works: useConsoleActionRuntime registers a script handler, and registered handlers beat ActionRunner's built-ins.
Every other consumer of @object-ui/core — standalone renderers, SDUI hosts, embedded usage — registers no such handler, falls through to the built-in executeScript, and now gets a clear error telling them a body must run server-side. Clear, but still a dead end: there is no supported way to make it run without hand-rolling the dispatcher that app-shell already has.
serverActionHandler needs three things core has no opinion about today:
auth — authFetch, session/token plumbing;
base URL — app-shell reads VITE_SERVER_URL, a bundler-specific env convention core should not inherit;
object resolution — which object the action is scoped to (objApiName), plus the record-id resolution dance (_rowRecord, recordIdField, toolbar selection fallback).
Adding a default dispatcher means core acquires opinions on all three, or takes them as injected config. That is a design decision, not a patch.
Options worth weighing
A factory in core — createServerActionHandler({ fetch, baseUrl, resolveObject }) that consumers register themselves. Core stays opinion-free; the duplicated logic in useConsoleActionRuntime and RecordDetailView (which both hand-roll the same POST) collapses into one place.
A registered-by-default handler wired from an existing provider (DataSourceProvider?) when one is present, so the common case needs no wiring.
Option 1 looks strongest: it fixes the existing duplication between useConsoleActionRuntime and RecordDetailView regardless of whether standalone consumers ever adopt it, so it earns its keep either way.
Not in scope
Executing bodies client-side, in any form. L2 requires an isolated VM enforcing declared capabilities, timeoutMs and memoryMb — a browser has none, so client-side "enforcement" would be decoration. L1 is formula-engine (CEL) source, a different dialect from this package's ${…}ExpressionEvaluator, so interpreting it here would diverge silently. The client dispatches; it does not interpret. See #2896 for the full reasoning.
Split out of #2896, which is closed — the fix there was to stop mislabeling a server-side
body("No script provided for script action" → an error naming the real cause). This is the follow-up that #2896 explicitly deferred, filed so it is not buried in a closed issue.Where things stand after #2895
ActionSchema.body(HookBodySchema— L1 expression / L2 sandboxed JS) is the spec's preferred binding for script actions. Bodies execute server-side, viaPOST /api/v1/actions/{object}/{action}→ the runtime sandbox.In the console this works:
useConsoleActionRuntimeregisters ascripthandler, and registered handlers beatActionRunner's built-ins.Every other consumer of
@object-ui/core— standalone renderers, SDUI hosts, embedded usage — registers no such handler, falls through to the built-inexecuteScript, and now gets a clear error telling them a body must run server-side. Clear, but still a dead end: there is no supported way to make it run without hand-rolling the dispatcher thatapp-shellalready has.Why it wasn't done in #2895
serverActionHandlerneeds three things core has no opinion about today:authFetch, session/token plumbing;app-shellreadsVITE_SERVER_URL, a bundler-specific env convention core should not inherit;objApiName), plus the record-id resolution dance (_rowRecord,recordIdField, toolbar selection fallback).Adding a default dispatcher means core acquires opinions on all three, or takes them as injected config. That is a design decision, not a patch.
Options worth weighing
createServerActionHandler({ fetch, baseUrl, resolveObject })that consumers register themselves. Core stays opinion-free; the duplicated logic inuseConsoleActionRuntimeandRecordDetailView(which both hand-roll the same POST) collapses into one place.DataSourceProvider?) when one is present, so the common case needs no wiring.target/execute, and stop mislabeling server-sidebody#2895 as the whole answer — defensible if standalone body use is genuinely rare.Option 1 looks strongest: it fixes the existing duplication between
useConsoleActionRuntimeandRecordDetailViewregardless of whether standalone consumers ever adopt it, so it earns its keep either way.Not in scope
Executing bodies client-side, in any form. L2 requires an isolated VM enforcing declared capabilities,
timeoutMsandmemoryMb— a browser has none, so client-side "enforcement" would be decoration. L1 is formula-engine (CEL) source, a different dialect from this package's${…}ExpressionEvaluator, so interpreting it here would diverge silently. The client dispatches; it does not interpret. See #2896 for the full reasoning.Refs #2895, #2896.