Skip to content

Expression validator uses incorrect default values for ri! inputs #10

Description

@jrank

Problem

When creating or updating an interface via the API, the expression validator evaluates ri! inputs using inappropriate default test values. This causes valid interfaces to fail creation with errors that do not occur when saving the same expression in Appian Designer.

Evidence

Tested against the API with sample interfaces:

Integer input bound to dropdown:

  • Expression: a!dropdownField(label: "Status", placeholder: "Select...", choiceLabels: {"Open", "Closed"}, choiceValues: {1, 2}, value: ri!statusId, saveInto: {})
  • Input: statusId (Number Integer)
  • Error: "value was 0 and choiceValues was 1; 2"
  • Root cause: validator evaluates ri!statusId as 0 (Integer default) instead of null

Text input bound to dropdown:

  • Expression: same dropdown with Text choiceValues and ri!status (Text)
  • Error: "value was placeholder and choiceValues was OPEN; CLOSED"
  • Root cause: validator evaluates ri!status as the literal string "placeholder"

Map input indexed with field name:

  • Expression: a!textField(label: "Name", value: ri!record["name"], saveInto: {})
  • Input: record (Map)
  • Error: "Cannot index property 'name' of type Text into type Text"
  • Root cause: validator coerces Map input to Text type

Defensive null check doesn't help:

  • Expression: if(a!isNullOrEmpty(ri!record), null, ri!record["name"])
  • Still fails with same error — validator appears to evaluate both branches

Expected Behavior

The expression validator should match in-product (Appian Designer) behavior. Options:

  • Skip evaluation of ri! references at save time (treat them as symbolic)
  • Use type-appropriate null defaults (null for Integer, null for Text, empty map for Map)
  • Short-circuit conditional branches so defensive patterns work

Impact

Any interface using ri! inputs in dropdowns or indexing into complex ri! inputs cannot be created via the API without workarounds that distort the SAIL code (e.g., if(ri!statusId = 0, null, ri!statusId)). These workarounds are unnecessary in Designer and add noise to the expression.

Metadata

Metadata

Assignees

No one assigned

    Labels

    tool-change-proposalProposed change to MCP tool behavior (not skill content)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions