Skip to content

AI Form Builder

This guide describes how a developer uses the AI Form Builder in Module Suite 4.1.0 (Polaris) to generate an AI View, store it on a Beautiful WebForms view, and run that view on Content Server and on Module Suite Runtime (MSR).

The AI View

An AI View is a Beautiful WebForms view. The form is still a Beautiful WebForms form, and the AI View is one version of that form's view. The same view can be opened as a form page, or mounted in a region of a Shell Page.

When a Shell Page mounts the AI View, the form keeps its own lifecycle. The Shell records that the form is dirty, and it applies the submit result as navigation or as a reload of the region. A list that opened the form can be shown again after the user submits or discards the form. To get this behavior, the list opens the form in its own region and passes returnComponentKey.

The page loads the view's script and styles for a specific view id and version id. The field definition and the rules travel with the page, so the form can validate on the first render.

What the view stores

The table lists what the AI Form Builder stores on the view and where each value comes from.

Item Where it comes from
View version Each stored result is a new version, addressed by the view id and the version id. A version never changes.
Field definition and rules Produced with the version. The page includes them, so the form needs no extra request to validate.
Delivery platform The Delivery platform select. Stored as targetHost.
Design Profile id The profile resolved by the last successful Generation run or compile. The id is pinned on the view.
Widget library and runtime version Set when you save the AI View.
Authored CSS The CSS you write. The builder stores and shows this CSS only.

Opening the builder and storing a view version

The AI Form Builder opens from a Beautiful WebForms view. It is the same builder on Content Server and on Module Suite Runtime.

A Generation run produces the form. The run is an Aether generation. Aether configuration is separate from the Content Script API. The host supplies the Content Server API dictionary for the run, and the model can read the API of a returned object before it writes a call. The editor can select a model for the run, or leave the selection on Auto. A run can continue the previous conversation.

The builder stores the result as a new version of the view. The published version is addressed by the view id and the version id. Saving the AI View sets the widget library and the runtime version on that view.

flowchart LR
    BwfView["Beautiful WebForms view"] --> Builder["AI Form Builder"]
    Builder --> Settings["Design language, Delivery platform, model or Auto"]
    Settings --> Run["Generation run (Aether)"]
    Run --> Version["View version (immutable)"]
    Version --> Pin["Pinned Design Profile id and Delivery platform"]
    Version --> CsPage["AI View page on Content Server"]
    Version --> ShellRegion["Shell Page region"]
    Version --> MsrForm["Remote form on MSR"]

You start from a view and choose the run settings in the builder. Each Generation run ends in a new, immutable view version that records its Design Profile and Delivery platform. That version can then render as a form page, in a Shell Page region, or as a remote form on Module Suite Runtime.

Choosing the Delivery platform

The builder has a Delivery platform select. The two platforms are Content Server and Module Suite Runtime. The selected platform is stored on the view and is sent with every Generation run. The default is the platform where the view is stored. A view keeps the platform it already has.

The stored value is targetHost:

Delivery platform targetHost value
Content Server content-server
Module Suite Runtime script-console

Only these two values are accepted. Any other value is ignored. A view that has no stored platform behaves as it did before.

The Delivery platform drives these parts of a run:

  • The Design Profile host default.
  • The guidance for Smart View pickers.
  • The preview's host styling.

Choose the platform where the form will be used, not the platform where you build it. For example, you can build a form on Module Suite Runtime for later use on Content Server.

Moving a version to the other platform

To use a version on the other platform, open History, then Download, and upload that package on the other host. The upload reports the platform and one line for each data source URL. Those lines are warnings. The upload still accepts the version.

Upload warnings are hints

A data source URL in the warnings may still work on the other platform. Check each one before users rely on the form.

The preview follows the selected platform's styling. It exercises that platform only. The preview does not run the other platform's data sources, submits, or REST calls. A notice under the Delivery platform select, and in the preview, explains how to move the version.

The V16 runtime

An AI View renders with the V16 runtime. V16 is the runtime Module Suite 4.1.0 ships.

A V16 view works on a small screen and on a touch screen. The V16 buttons submit the form and save it.

The V16 runtime loads the Design Profile when the view opens. A runtime that has no design files receives no design context.

Design Profiles and delivery

AI forms and each Shell Component share one Design Profile model and one delivery model.

A Design Profile is a visual language. The shipped profiles are jato, studio, and portal.

Profile Look Light and dark mode
jato Follows Content Server Smart View. On the portal it keeps the Smart View look. Follows the host.
portal Follows the portal and Content Server. Follows the host.
studio Uses fixed values. Always light. It stays light on a dark host.

The Design language select in the AI Form Builder chooses the profile for a Generation run. The same profile ids are used for a Shell Component. Set the look with this select, and put any other styling in the view's CSS.

Host defaults

An administrator sets one default profile for each host:

Host Setting
Content Server design.profile.content_server
Module Suite Runtime portal design.profile.portal

A Generation run whose Delivery platform is Module Suite Runtime uses the portal default. Any other run uses the Content Server default. Every MSR artifact uses the portal default. The host default applies when the view names no profile and has never been pinned.

Tip

Changing a host default does not restyle existing AI Views. They keep their pinned profile id.

Resolution and pinning

Resolution uses the profile named for the run, then the profile stored on the view, then the host default. After a successful Generation run or compile, the resolved profile id is pinned on the view. The pin is set even when the run named a different profile from the one stored on the view.

flowchart TD
    Start["Generation run or compile"] --> RunProfile{"Profile named for the run?"}
    RunProfile -- Yes --> UseRun["Use the run profile"]
    RunProfile -- No --> Stored{"Profile stored on the view?"}
    Stored -- Yes --> UseStored["Use the stored profile"]
    Stored -- No --> UseDefault["Use the host default"]
    UseRun --> PinId["Pin the resolved id on the view"]
    UseStored --> PinId
    UseDefault --> PinId
    PinId --> Open["View opens in the runtime"]
    Open --> Check{"Pinned id empty or unknown?"}
    Check -- Empty --> Jato["Use jato"]
    Check -- Unknown --> JatoWarn["Use jato and write a console warning"]
    Check -- Known --> Profile["Use the pinned profile"]

The profile is resolved when a Generation run or compile succeeds, and the result is pinned on the view. The runtime applies the jato fallback when the view opens, so a wrong id never stops the form from rendering.

The pin keeps the id. The runtime supplies the current values when the view opens, so a change to a profile reaches every AI View that uses it after the next runtime deployment. The stored view version stays in place. A Shell Component whose bundle still contains older compiled values needs one recompile.

An empty profile id uses jato. An unknown profile id uses jato and writes a console warning. A Shell Page uses the profile pinned on the view. A Shell Page cannot set the profile of the form it mounts.

Note

Two AI Views with different profiles can share one page. Each form keeps its own profile. The builder preview shows one profile at a time.

Light and dark mode

The host decides light or dark mode. jato and portal follow that mode. The standalone AI View page on Module Suite Runtime is always light.

The runtime reads these attributes on the page's <html> element:

Host Attributes
Content Server data-smart-theme, data-jato-theme
Portal data-theme

The mode is dark when any of these attributes is dark. Otherwise it is light. The runtime does not read the operating system color preference. It writes the resolved mode as data-ds-mode on the form's mount element.

How the view's CSS combines with the profile

The profile supplies its values as --ds-* CSS variables, for example --ds-color-surface.

The view's own CSS is applied after the profile, so authored rules override the profile's kit styling. Spacing and the standard text sizes stay as compiled values. They do not follow the host.

Warning

Authored rules that target kit controls always take precedence over the profile. Review those rules if a form does not follow its Design Profile.

The runtime loads the Inter font only. A profile font such as the one studio uses shows only when the host page loads that font.

Smart View pickers

A developer can mark a Smart View picker on an AI form. The field is an integer. In the builder Type select, choose the node picker or the member picker. The form stores ids only.

In the field definition, a picker field is an INTEGER field with a widget hint:

Picker widget value
Node picker node-picker
Member picker member-picker

Content Server categories and the server validators treat the field as a plain integer. A Generation run refuses the hint on a field of another type.

  • With multiplicity 1, the value is one id, or empty.
  • With multiplicity N, the value is a list of at most N ids, with duplicates dropped.
  • A set row shows a multi-value picker as one control.
  • A required field treats an empty list as missing, in the browser and on submit.

Where the picker opens

Where the picker opens depends on the host:

  • On a Content Server V16 AI View page, the picker uses that page's Smart View context.
  • In a Shell Page region on Content Server, the picker uses the region's host widget service.
  • In a portal region on Module Suite Runtime, the picker uses the region's host widget service. Content Server is loaded with the user's token.
  • In the AI Form Builder preview, the picker offers sample folders, users, and groups.
  • On the standalone AI View page on Module Suite Runtime, pickers are unavailable.
flowchart TD
    Field["Picker field on an AI View"] --> Host{"Where does the form run?"}
    Host --> CsPage["Content Server V16 AI View page"]
    Host --> CsShell["Shell Page region on Content Server"]
    Host --> MsrRegion["Portal region on MSR"]
    Host --> Preview["AI Form Builder preview"]
    Host --> MsrPage["Standalone AI View page on MSR"]
    CsPage --> PageContext["Page's Smart View context"]
    CsShell --> RegionService["Region's host widget service"]
    MsrRegion --> RegionToken["Region's host widget service, Content Server loaded with the user's token"]
    Preview --> Samples["Sample folders, users, and groups"]
    MsrPage --> NoPicker["Unavailable: button disabled, reason shown"]

The same picker field works on every host. Only the source of the picker changes. On the standalone Module Suite Runtime page, the form still renders and shows why the picker cannot open. That page has no Content Server connection of its own.

Until the host has finished loading, a click waits. When the picker is available, it opens. When it is unavailable, the button is disabled and the form shows the reason. On a required field that is still empty, that reason is the message the user sees.

The form can show names for ids the current user is allowed to read. Ids the user cannot read show no name. An AI form entry receives the host widget capability (hostWidget) by default, on Content Server and on Module Suite Runtime, so it can also embed a Smart View widget. A page author can turn that capability off on Content Server. An AI form does not receive the REST client capability.

Checking picked ids on the server

A picked id arrives from the browser. In the view's PreSubmit or OnSubmit script, load the id as the submitting user, check its type, and stop with a clear error when the id is missing or is the wrong type.

Do not trust a picked id

A crafted submit can carry any id. The server validators only check that the value is an integer. The type and access check belongs in the view's scripts.

Pickers in a Generation run

On a Generation run for Content Server, the builder prefers these pickers. It still uses a remote list for an anonymous form and for a fixed list. A run that points a data source or a view URL at the members or search API produces a warning. On a Generation run for Module Suite Runtime, the builder allows pickers for a form that will be placed in a portal region, and it warns when a picker is required. A required picker cannot be filled on the standalone Module Suite Runtime page. The form still renders there and shows why the picker cannot open.

Warning When it appears
form_custom_csui_picker Content Server run. A data source or a view URL points at the members or search API.
form_required_picker_on_msr Module Suite Runtime run. A picker field is required.

Scripts, validation, and styles

A Shell-mounted AI View runs its OnLoad script. After an action roundtrip, the changes made by that script are still present.

Validation names the field that failed. During a recompile, an omitted fieldset field produces a warning. The recompile continues.

The AI Form Builder stores and shows the authored CSS only. A later Generation run keeps that CSS. Saving the AI View sets the widget library and the runtime version.

If the field definition cannot be loaded, validation stops with the message "This form cannot be validated because its field definition is unavailable." The submit is rejected.

Before a submit is validated, the node rebuilds the view version's files if they are missing. An AI View version is never validated as a classic view because its files are missing on that node.

Submit and the folder path

An AI View submit keeps the folder path. That includes an anonymous submit from a public folder.

The V16 buttons submit the form and save it. On a Shell Page, submit or discard returns a list that opened the form.

Serving the view on each cluster node

Each cluster node can serve the AI form files for that node. Any node can render, serve, and validate any AI View version. The cluster needs no shared support folder and no sticky sessions.

The page requests the script and the styles at:

{cgi}/amwf/aiv/{viewId}/{versionNum}/bundle.js
{cgi}/amwf/aiv/{viewId}/{versionNum}/styles.css

viewId is the view id and versionNum is the version id. The route accepts no other file name. A version is immutable, so when the node has the file, the response is marked as cacheable without expiry. The field definition and the rules are included in the page.

When the files are missing on the node that received the request, that node checks the view as the requesting user. The user must be able to read the view, and the version must exist. The node then rebuilds the files from the stored version and serves the complete file. The same user who can render the form can cause that rebuild. The next request on that node is served from the node's copy. A version created before the current generation metadata can be rebuilt the same way.

sequenceDiagram
    participant Browser
    participant Node as Cluster node
    participant Store as Stored view version
    Browser->>Node: GET .../amwf/aiv/{viewId}/{versionNum}/bundle.js
    alt File is on the node
        Node-->>Browser: 200, complete file, cacheable
    else File is missing
        Node->>Node: Check as the requesting user
        alt Not an AI View, no such version, or user cannot read the view
            Node-->>Browser: 404
        else Check passes
            Node->>Store: Read the stored version
            Store-->>Node: Version content
            Node->>Node: Rebuild and write each file whole
            alt Rebuild fails
                Node-->>Browser: 500
            else Rebuild succeeds
                Node-->>Browser: 200, complete file
            end
        end
    end

A node that lacks the files checks access first, then rebuilds them from the stored version. A browser never receives a partial file. The 404 answer is the same for an unknown id, a classic view, a missing version, and a view the user cannot read, so the route does not reveal which ids exist.

Note

A file that is already on a node is served without a per-user check. The permission check runs only when the node must rebuild the files.

The same rebuild runs during submit. If the files cannot be rebuilt, the submit is rejected.

File addresses on a page

A Shell Page uses this route for an AI View unless the page author set a bundle or styles address (aiBundleURL, bundleUrl, or aiStylesURL). An address that points at the support folder on one node works on that node.

The V16 AI View template reads these view parameters:

View parameter Holds Cluster-safe
aiBundleHref The route address of bundle.js Yes
aiStylesHref The route address of styles.css Yes
aiBundleURL, aiStylesURL, aiFieldsetURL, aiRulesURL Support folder addresses No

When aiBundleHref or aiStylesHref is empty, the template uses the support folder address. A copied template that still uses the support folder addresses keeps working, but only on the node that holds the files.

A remote form on Module Suite Runtime

An AI form can run on Module Suite Runtime as a remote form. The portal hosts it in a region of a Shell Page.

A form on Module Suite Runtime uses its own script values, with no dependency on the OpenText library that Content Server uses for those values. The default remote-form action refreshes the form.

Set the Delivery platform to Module Suite Runtime when the form is meant to run there. The standalone AI View page on Module Suite Runtime is always light, and pickers are unavailable on that page. The same form in a portal region uses the portal Design Profile default, the portal light and dark mode, and the Smart View pickers.

To mount the form in a portal region, add an entry to the registry of the portal Shell Page, under a key that does not start with portal.:

{ "aiView": "{formId}:{viewId}" }
Key Value
aiView The form id and the view id, separated by a colon.
version Optional. The version number of the view to mount.

When the region mounts the form, Module Suite Runtime runs the form's OnLoad script and keeps the form state on the server. A submit in the region validates the values, stores them, and keeps the form in the region.

The region follows the form's remote-form access rules. The entry is dropped when the form is PIN-protected and the PIN is not yet verified in the session, or when the form is expired, inactive, or not visible to the user. A PIN-protected form runs as a standalone page only. The same AI View can be both a standalone page and a region.

Reading an AI View definition from a script

A form record stores attribute names and raw values. forms.formToMap(record) returns keys such as forecast_Date, wraps every value in a list, also for a single-valued field, and keeps the stored code of an ENUM choice (full_time), not its label. The AI View knows the labels, the sections, and the choice labels that users saw.

From Module Suite 4.1.0, forms.getAiViewDefinition returns that definition, and describe(record) applies it to one record. Use it when a script needs the labels and sections users saw: reports, notifications, exports, and agents that summarize a submission. The API replaces hardcoded labels and reading the AI Form Builder's internal state, whose layout is not an API.

flowchart LR
    FormNode["Form or AI View node"] --> GetDefinition["forms.getAiViewDefinition(node)"]
    GetDefinition --> Definition["CSAiViewDefinition"]
    Definition --> Sections["sections: CSAiViewSection"]
    Sections --> Fields["fields: CSAiViewField (label, type, options)"]
    FormRecord["Form record, e.g. forms.listFormData(formID, seq)"] --> Describe["definition.describe(record)"]
    Definition --> Describe
    Describe --> ViewRecord["CSAiViewRecord"]
    ViewRecord --> AnswerGroups["sections: CSAiViewAnswerGroup"]
    AnswerGroups --> Answers["answers: CSAiViewAnswer (label, displayValue)"]
    ViewRecord --> Additional["additionalAnswers: attributes the view does not describe"]

The definition describes the view: its sections and fields. describe(record) combines the definition with one stored record and returns the answers grouped by section, with labels and display values. Stored attributes that the view does not describe are kept apart in additionalAnswers.

Reading the definition

Method Description Since
forms.getAiViewDefinition(node) Returns the CSAiViewDefinition of an AI View. node is an AI View, or a form. For a form, the method uses the form's view when that view is an AI View, else the first AI View of the form template. Returns null when there is no AI View or the view has no saved definition. 4.1.0
forms.getAiViewDefinition(view, viewVersionNum) Returns the CSAiViewDefinition of one version (Long) of an AI View. Returns null when the node is not an AI View or the version has no saved definition. 4.1.0
form.aiViewDefinition The definition of the form's AI View, as forms.getAiViewDefinition(form) returns it. null when the form has no AI View. 4.1.0
view.aiViewDefinition The definition of an AI View node, as forms.getAiViewDefinition(view) returns it. null when the node is not an AI View. 4.1.0

By default the definition is read from the version Content Server renders, not from the editor's latest draft, so the labels match what users saw when they submitted. The definition is read from the stored view version, so the result is the same whichever front-end renders the form. Use the two-argument form to read an older version, for example the version a record was submitted with.

The view is read again with the permissions of the script's user. When that user cannot read the AI View, both methods throw an ExecutionFaultException.

Definition objects

CSAiViewDefinition

Member Description Since
viewId long node ID of the AI View. 4.1.0
viewName String name of the AI View node. 4.1.0
viewVersionNum long version of the AI View the definition was read from. 4.1.0
sections List of CSAiViewSection, in view order. 4.1.0
fields List of all top-level CSAiViewField data fields, in view order. 4.1.0
getField(name) Returns the top-level field with that name, or null. name is the field name (forecastdate) or its stored attribute name (forecast_Date). 4.1.0
describe(record) Returns a CSAiViewRecord: the Form record grouped and labelled as in the view. 4.1.0
describe(values) The same, for a Map of record values as returned by forms.formToMap(record). 4.1.0

CSAiViewSection

Member Description Since
name String section name, or an empty string for the fields before the first section. 4.1.0
label String section heading shown by the AI View, or an empty string for the fields before the first section. 4.1.0
fields List of the CSAiViewField data fields of the section, in view order. 4.1.0

CSAiViewField

Member Description Since
name String field name in the AI View definition, for example forecastdate. 4.1.0
storageKey String attribute name of the field in the form record, as returned by forms.formToMap, for example forecast_Date. 4.1.0
type String field type: TEXT, INTEGER, DECIMAL, BOOLEAN, DATE, DATETIME, ENUM, or SET. 4.1.0
label String label shown by the AI View. 4.1.0
placeholder String placeholder text, or an empty string. 4.1.0
helpMessage String help text shown below the field, or an empty string. 4.1.0
required boolean, true when the AI View requires a value. 4.1.0
multiplicity int number of values the field accepts. 1 for a single value. 4.1.0
options List of the CSAiViewOption choices of an ENUM field. Empty for other types and for an ENUM field fed by a data source. 4.1.0
fields List of the CSAiViewField sub-fields of a repeating group (SET). Empty for other types. 4.1.0
set boolean, true for a repeating group (SET). 4.1.0
getOptionLabel(value) Returns the label of the choice whose stored value matches value, or the value itself when no choice matches. 4.1.0

CSAiViewOption

Member Description Since
value String value stored in the form record. 4.1.0
label String label shown by the AI View. 4.1.0

Describing a record

describe(record) accepts a Form record, for example from forms.listFormData(formID, seq), or the Map that forms.formToMap(record) returns. It does the work a script would otherwise do by hand:

  • It matches each stored key to a field, ignoring case and delimiters, so forecastdate in the view matches forecast_Date in the record.
  • It unwraps single values from the list that formToMap puts around them.
  • It maps ENUM values to their choice labels.
  • It walks the rows of a repeating group (SET). Each non-empty row becomes one answer group in entries.
  • It returns the stored attributes that the view does not describe in additionalAnswers, with a label derived from the attribute name. Fields removed from the view, or added to the form template by hand, are never dropped.

CSAiViewRecord

Member Description Since
sections List of CSAiViewAnswerGroup, one for each AI View section that has data fields, in view order. 4.1.0
additionalAnswers List of CSAiViewAnswer for the stored attributes that the AI View does not describe, with labels derived from the attribute names. 4.1.0
questionCount int number of answers in the sections and the additional answers. 4.1.0
answeredCount int number of non-empty answers in the sections and the additional answers. 4.1.0

CSAiViewAnswerGroup holds the answers of one section, or of one row of a repeating group.

Member Description Since
name String section name. An empty string for the fields before the first section and for a repeating group row. 4.1.0
label String section heading. An empty string for the fields before the first section and for a repeating group row. 4.1.0
answers List of CSAiViewAnswer in view order, including empty answers. 4.1.0
empty boolean, true when no answer of the group holds a value. 4.1.0

CSAiViewAnswer is the answer of the record to one field.

Member Description Since
field The CSAiViewField of the answer, or null for a stored attribute that the AI View does not describe. 4.1.0
name String field name, or the stored attribute name when the AI View does not describe it. 4.1.0
label String label shown by the AI View, or a label derived from the attribute name. 4.1.0
values List of the stored non-empty values (Date for date fields). Empty for a repeating group. 4.1.0
value Object first stored value, or null when the answer is empty. 4.1.0
displayValues List of String display values: the choice label for ENUM, Yes or No for BOOLEAN, yyyy-MM-dd for DATE, yyyy-MM-dd HH:mm for DATETIME. 4.1.0
displayValue String display values joined by new lines, or an empty string when the answer is empty. 4.1.0
entries List of CSAiViewAnswerGroup, one for each non-empty row of a repeating group (SET). Empty for other fields. 4.1.0
set boolean, true for the answer to a repeating group (SET). 4.1.0
empty boolean, true when the record holds no value for the field. For a SET, true when it has no non-empty row. 4.1.0

Other date formats

Display values use fixed date formats. For another format, format answer.values yourself. Dates are formatted in the server time zone, the zone formToMap parses them in, so a date-only value stays on its day.

How sections are grouped

Sections come from the SECTION fields of the AI View:

  • A SECTION either nests its own fields, or groups the top-level fields that follow it until the next SECTION.
  • The fields before the first SECTION form an unnamed group: its name and label are empty strings. A view without SECTION fields has one such group. Give it a heading of your own.
  • A section without data fields is left out.

What the definition does not include

The definition describes the labels, types, choices, and grouping of the fields. It does not include the view's rules, its data sources, or its locales. An ENUM field fed by a data source has no options, so describe shows its stored value.

Example: Turning a form record into a labelled report

def formNode = docman.getNodeByNickname('expense_claims')
def record = forms.listFormData(formNode.ID, 42L)      // one record, by sequence number
def definition = forms.getAiViewDefinition(formNode)
if (!definition) {
    throw new IllegalStateException('The form has no AI View with a saved definition')
}
def described = definition.describe(record)
out << "${definition.viewName}: ${described.answeredCount} of ${described.questionCount} questions answered\n"
described.sections.eachWithIndex { section, i ->
    out << "== ${section.label ?: (i == 0 ? 'Details' : 'Further details')}\n"
    section.answers.each { answer ->
        if (answer.set) {
            answer.entries.eachWithIndex { entry, n ->
                entry.answers.each { sub -> out << "${answer.label} ${n + 1} / ${sub.label}: ${sub.displayValue}\n" }
            }
        } else {
            out << "${answer.label}: ${answer.empty ? 'Not provided' : answer.displayValue}\n"
        }
    }
}
if (described.additionalAnswers) {
    out << "== Additional information\n"
    described.additionalAnswers.each { answer -> out << "${answer.label}: ${answer.displayValue}\n" }
}

The script reads one record and the definition of the form's AI View, then writes each section heading followed by its labelled answers. Rows of a repeating group are numbered. Attributes the view does not describe are listed at the end, so no stored value is lost.

Requires Module Suite 4.1.0

forms.getAiViewDefinition and the CSAiView objects are available from Module Suite 4.1.0. On older versions, derive labels from the attribute names that forms.formToMap(record) returns.

Troubleshooting

The form does not render

  • Request the bundle.js and styles.css addresses directly. A 404 means the view is not an AI View, the version does not exist, or the user cannot read the view. A 500 means the node could not rebuild the files.
  • Check the view id and the version id in the address.
  • If the form renders on one node only, check whether the Shell Page sets a support folder address (aiBundleURL, aiStylesURL, or bundleUrl). Remove the address so the page uses the route. In a copied template, use aiBundleHref and aiStylesHref.

The submit is rejected

  • The message "This form cannot be validated because its field definition is unavailable." means the node could not load the field definition for that version.
  • A submit is also rejected when the node cannot rebuild the version's files.
  • Validation names the field that failed. Check that field first.

The look is not what you expect

  • An unknown profile id falls back to jato and writes a console warning. Check the browser console.
  • A profile change reaches the form after the next runtime deployment.
  • studio and the standalone AI View page on Module Suite Runtime are always light.
  • For dark mode, check the <html> attributes of the host page and data-ds-mode on the form's mount element.
  • Authored CSS overrides the profile's kit styling.

A picker does not open

  • Read the reason the form shows under the disabled button.
  • On the standalone AI View page on Module Suite Runtime, pickers are unavailable. Mount the form in a portal region instead.
  • On Content Server, check whether the page author turned off the host widget capability. A cached Shell Page definition keeps the capabilities it had until the cache is refreshed.
  • A picked id shows no name when the current user cannot read it.

A portal region on Module Suite Runtime shows no form

  • Check that the registry key does not start with portal..
  • Check that the form is active, not expired, visible to the user, and not PIN-protected.