@uipath/skills 1.204.0 → 1.204.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.cursor-plugin/plugin.json +1 -1
  4. package/CODEOWNERS +12 -14
  5. package/package.json +1 -1
  6. package/skills/uipath-agents/references/coded/embedding-in-flows.md +1 -3
  7. package/skills/uipath-agents/references/coded/quickstart.md +0 -2
  8. package/skills/uipath-agents/references/lowcode/capabilities/inline-in-flow/inline-in-flow.md +10 -8
  9. package/skills/uipath-agents/references/lowcode/prompting/autonomous-agent-prompting-guide.md +1 -1
  10. package/skills/uipath-human-in-the-loop/SKILL.md +1 -3
  11. package/skills/uipath-human-in-the-loop/references/hitl-node-apptask.md +0 -2
  12. package/skills/uipath-human-in-the-loop/references/hitl-node-coded-action-app.md +0 -2
  13. package/skills/uipath-human-in-the-loop/references/hitl-node-quickform.md +2 -2
  14. package/skills/uipath-maestro-flow/.maintenance/README.md +265 -0
  15. package/skills/uipath-maestro-flow/.maintenance/check-all.sh +40 -0
  16. package/skills/uipath-maestro-flow/.maintenance/check-anchors.sh +101 -0
  17. package/skills/uipath-maestro-flow/.maintenance/check-depth.sh +132 -0
  18. package/skills/uipath-maestro-flow/.maintenance/check-link-text.sh +123 -0
  19. package/skills/uipath-maestro-flow/.maintenance/check-links.sh +73 -0
  20. package/skills/uipath-maestro-flow/.maintenance/check-orphans.sh +93 -0
  21. package/skills/uipath-maestro-flow/.maintenance/check-plugin-pairs.sh +39 -0
  22. package/skills/uipath-maestro-flow/.maintenance/check-template.sh +42 -0
  23. package/skills/uipath-maestro-flow/.maintenance/check-uip-commands.sh +270 -0
  24. package/skills/uipath-maestro-flow/.maintenance/check-versions.sh +160 -0
  25. package/skills/uipath-maestro-flow/SKILL.md +69 -886
  26. package/skills/uipath-maestro-flow/references/author/CAPABILITY.md +207 -0
  27. package/skills/uipath-maestro-flow/references/author/brownfield.md +91 -0
  28. package/skills/uipath-maestro-flow/references/author/editing-operations-cli.md +190 -0
  29. package/skills/uipath-maestro-flow/references/author/editing-operations-json.md +374 -0
  30. package/skills/uipath-maestro-flow/references/author/editing-operations.md +104 -0
  31. package/skills/uipath-maestro-flow/references/author/greenfield.md +420 -0
  32. package/skills/uipath-maestro-flow/references/author/planning-arch.md +364 -0
  33. package/skills/uipath-maestro-flow/references/author/planning-impl.md +291 -0
  34. package/skills/uipath-maestro-flow/references/author/plugins/agent/impl.md +237 -0
  35. package/skills/uipath-maestro-flow/references/author/plugins/agent/planning.md +97 -0
  36. package/skills/uipath-maestro-flow/references/author/plugins/agentic-process/impl.md +107 -0
  37. package/skills/uipath-maestro-flow/references/author/plugins/agentic-process/planning.md +61 -0
  38. package/skills/uipath-maestro-flow/references/author/plugins/api-workflow/impl.md +108 -0
  39. package/skills/uipath-maestro-flow/references/author/plugins/api-workflow/planning.md +60 -0
  40. package/skills/uipath-maestro-flow/references/author/plugins/batch-transform/impl.md +171 -0
  41. package/skills/uipath-maestro-flow/references/author/plugins/batch-transform/planning.md +72 -0
  42. package/skills/uipath-maestro-flow/references/author/plugins/connector/impl-inline.md +120 -0
  43. package/skills/uipath-maestro-flow/references/author/plugins/connector/impl.md +463 -0
  44. package/skills/uipath-maestro-flow/references/author/plugins/connector/planning.md +186 -0
  45. package/skills/uipath-maestro-flow/references/author/plugins/connector-trigger/impl.md +517 -0
  46. package/skills/uipath-maestro-flow/references/author/plugins/connector-trigger/planning.md +115 -0
  47. package/skills/uipath-maestro-flow/references/author/plugins/conversational-agent/impl.md +309 -0
  48. package/skills/uipath-maestro-flow/references/author/plugins/conversational-agent/planning.md +133 -0
  49. package/skills/uipath-maestro-flow/references/author/plugins/data-fabric/impl.md +428 -0
  50. package/skills/uipath-maestro-flow/references/author/plugins/data-fabric/planning.md +188 -0
  51. package/skills/uipath-maestro-flow/references/author/plugins/decision/impl.md +83 -0
  52. package/skills/uipath-maestro-flow/references/author/plugins/decision/planning.md +38 -0
  53. package/skills/uipath-maestro-flow/references/author/plugins/delay/impl.md +38 -0
  54. package/skills/uipath-maestro-flow/references/author/plugins/delay/planning.md +53 -0
  55. package/skills/uipath-maestro-flow/references/author/plugins/end/impl.md +56 -0
  56. package/skills/uipath-maestro-flow/references/author/plugins/end/planning.md +28 -0
  57. package/skills/uipath-maestro-flow/references/author/plugins/flow/impl.md +107 -0
  58. package/skills/uipath-maestro-flow/references/author/plugins/flow/planning.md +58 -0
  59. package/skills/uipath-maestro-flow/references/author/plugins/hitl/impl.md +181 -0
  60. package/skills/uipath-maestro-flow/references/author/plugins/hitl/planning.md +166 -0
  61. package/skills/uipath-maestro-flow/references/author/plugins/http/impl-connector.md +86 -0
  62. package/skills/uipath-maestro-flow/references/author/plugins/http/impl-manual.md +68 -0
  63. package/skills/uipath-maestro-flow/references/author/plugins/http/impl.md +173 -0
  64. package/skills/uipath-maestro-flow/references/author/plugins/http/planning.md +107 -0
  65. package/skills/uipath-maestro-flow/references/author/plugins/inline-agent/impl.md +540 -0
  66. package/skills/uipath-maestro-flow/references/author/plugins/inline-agent/planning.md +115 -0
  67. package/skills/uipath-maestro-flow/references/author/plugins/inline-voice-agent/impl.md +269 -0
  68. package/skills/uipath-maestro-flow/references/author/plugins/inline-voice-agent/planning.md +128 -0
  69. package/skills/uipath-maestro-flow/references/author/plugins/ixp/impl.md +424 -0
  70. package/skills/uipath-maestro-flow/references/author/plugins/ixp/planning.md +95 -0
  71. package/skills/uipath-maestro-flow/references/author/plugins/loop/impl.md +403 -0
  72. package/skills/uipath-maestro-flow/references/author/plugins/loop/planning.md +60 -0
  73. package/skills/uipath-maestro-flow/references/author/plugins/merge/impl.md +43 -0
  74. package/skills/uipath-maestro-flow/references/author/plugins/merge/planning.md +24 -0
  75. package/skills/uipath-maestro-flow/references/author/plugins/queue/impl.md +82 -0
  76. package/skills/uipath-maestro-flow/references/author/plugins/queue/planning.md +44 -0
  77. package/skills/uipath-maestro-flow/references/author/plugins/rpa/impl.md +117 -0
  78. package/skills/uipath-maestro-flow/references/author/plugins/rpa/planning.md +61 -0
  79. package/skills/uipath-maestro-flow/references/author/plugins/scheduled-trigger/impl.md +56 -0
  80. package/skills/uipath-maestro-flow/references/author/plugins/scheduled-trigger/planning.md +93 -0
  81. package/skills/uipath-maestro-flow/references/author/plugins/script/impl.md +98 -0
  82. package/skills/uipath-maestro-flow/references/author/plugins/script/planning.md +42 -0
  83. package/skills/uipath-maestro-flow/references/author/plugins/subflow/impl.md +164 -0
  84. package/skills/uipath-maestro-flow/references/author/plugins/subflow/planning.md +35 -0
  85. package/skills/uipath-maestro-flow/references/author/plugins/summarize/impl.md +189 -0
  86. package/skills/uipath-maestro-flow/references/author/plugins/summarize/planning.md +66 -0
  87. package/skills/uipath-maestro-flow/references/author/plugins/switch/impl.md +72 -0
  88. package/skills/uipath-maestro-flow/references/author/plugins/switch/planning.md +34 -0
  89. package/skills/uipath-maestro-flow/references/author/plugins/terminate/impl.md +48 -0
  90. package/skills/uipath-maestro-flow/references/author/plugins/terminate/planning.md +29 -0
  91. package/skills/uipath-maestro-flow/references/author/plugins/transform/impl.md +252 -0
  92. package/skills/uipath-maestro-flow/references/author/plugins/transform/planning.md +47 -0
  93. package/skills/uipath-maestro-flow/references/diagnose/CAPABILITY.md +73 -0
  94. package/skills/uipath-maestro-flow/references/diagnose/failure-modes.md +353 -0
  95. package/skills/uipath-maestro-flow/references/diagnose/troubleshooting-guide.md +174 -0
  96. package/skills/uipath-maestro-flow/references/evaluate/CAPABILITY.md +134 -0
  97. package/skills/uipath-maestro-flow/references/evaluate/commands-reference.md +376 -0
  98. package/skills/uipath-maestro-flow/references/evaluate/eval-sets-guide.md +227 -0
  99. package/skills/uipath-maestro-flow/references/evaluate/evaluators-guide.md +143 -0
  100. package/skills/uipath-maestro-flow/references/evaluate/running-guide.md +215 -0
  101. package/skills/uipath-maestro-flow/references/evaluate/upload-safety.md +94 -0
  102. package/skills/uipath-maestro-flow/references/operate/CAPABILITY.md +77 -0
  103. package/skills/uipath-maestro-flow/references/operate/manage.md +39 -0
  104. package/skills/uipath-maestro-flow/references/operate/run.md +121 -0
  105. package/skills/uipath-maestro-flow/references/operate/ship.md +57 -0
  106. package/skills/uipath-maestro-flow/references/shared/action-nodes.md +100 -0
  107. package/skills/uipath-maestro-flow/references/shared/cli-commands.md +269 -0
  108. package/skills/uipath-maestro-flow/references/shared/cli-conventions.md +178 -0
  109. package/skills/uipath-maestro-flow/references/shared/file-format.md +582 -0
  110. package/skills/uipath-maestro-flow/references/shared/node-output-wiring.md +86 -0
  111. package/skills/uipath-maestro-flow/references/shared/ux-narration-and-todos.md +113 -0
  112. package/skills/uipath-maestro-flow/references/shared/variables-and-expressions.md +787 -0
  113. package/skills/uipath-platform/references/integration-service/activities.md +2 -2
  114. package/skills/uipath-platform/references/integration-service/activity-generation.md +8 -1
  115. package/skills/uipath-platform/references/integration-service/triggers.md +1 -3
  116. package/version-manifest.json +1 -1
  117. package/skills/uipath-maestro-flow/examples/AquariumSafetyStop.flow.ts +0 -26
  118. package/skills/uipath-maestro-flow/examples/ArchiveCardExtract.flow.ts +0 -38
  119. package/skills/uipath-maestro-flow/examples/BakeOffEntryForm.flow.ts +0 -27
  120. package/skills/uipath-maestro-flow/examples/BeeHiveLedger.flow.ts +0 -61
  121. package/skills/uipath-maestro-flow/examples/BeltProgression.flow.ts +0 -53
  122. package/skills/uipath-maestro-flow/examples/BirdCountLookup.flow.ts +0 -24
  123. package/skills/uipath-maestro-flow/examples/ClubDirectory.flow.ts +0 -56
  124. package/skills/uipath-maestro-flow/examples/ConcertSoundcheck.flow.ts +0 -59
  125. package/skills/uipath-maestro-flow/examples/DoorbellLog.flow.ts +0 -45
  126. package/skills/uipath-maestro-flow/examples/FestivalMapScaffold.flow.ts +0 -22
  127. package/skills/uipath-maestro-flow/examples/FieldTripQuickForm.flow.ts +0 -45
  128. package/skills/uipath-maestro-flow/examples/FossilCatalogEnrich.flow.ts +0 -26
  129. package/skills/uipath-maestro-flow/examples/GallerySubmission.flow.ts +0 -67
  130. package/skills/uipath-maestro-flow/examples/GreenhouseWatering.flow.ts +0 -39
  131. package/skills/uipath-maestro-flow/examples/HarbourRadioLine.flow.ts +0 -31
  132. package/skills/uipath-maestro-flow/examples/HerbariumDispatch.flow.ts +0 -34
  133. package/skills/uipath-maestro-flow/examples/KilnReview.flow.ts +0 -38
  134. package/skills/uipath-maestro-flow/examples/LibraryDeskChat.flow.ts +0 -39
  135. package/skills/uipath-maestro-flow/examples/LighthouseSignal.flow.ts +0 -30
  136. package/skills/uipath-maestro-flow/examples/MeteorShowerPages.flow.ts +0 -39
  137. package/skills/uipath-maestro-flow/examples/NeighborhoodWalkPlanner.flow.ts +0 -27
  138. package/skills/uipath-maestro-flow/examples/ObservatorySeeing.flow.ts +0 -51
  139. package/skills/uipath-maestro-flow/examples/OralHistoryDigest.flow.ts +0 -31
  140. package/skills/uipath-maestro-flow/examples/PlanetariumConfirmation.flow.ts +0 -34
  141. package/skills/uipath-maestro-flow/examples/PlantNameAdvisor.flow.ts +0 -28
  142. package/skills/uipath-maestro-flow/examples/PostcardCaption.flow.ts +0 -44
  143. package/skills/uipath-maestro-flow/examples/PotteryStudioCallback.flow.ts +0 -41
  144. package/skills/uipath-maestro-flow/examples/RecipeScaler.flow.ts +0 -62
  145. package/skills/uipath-maestro-flow/examples/SeedPacketReader.flow.ts +0 -49
  146. package/skills/uipath-maestro-flow/examples/TideTableConverter.flow.ts +0 -35
  147. package/skills/uipath-maestro-flow/examples/TrailLogSummary.flow.ts +0 -75
  148. package/skills/uipath-maestro-flow/examples/WorkshopInventory.flow.ts +0 -27
  149. package/skills/uipath-maestro-flow/examples/bindings.json +0 -85
  150. package/skills/uipath-maestro-flow/references/CLI-LOOP.md +0 -309
  151. package/skills/uipath-maestro-flow/references/agent-resources.md +0 -74
  152. package/skills/uipath-maestro-flow/references/agent.md +0 -175
  153. package/skills/uipath-maestro-flow/references/agentic-process.md +0 -41
  154. package/skills/uipath-maestro-flow/references/api-workflow.md +0 -29
  155. package/skills/uipath-maestro-flow/references/author.md +0 -178
  156. package/skills/uipath-maestro-flow/references/batch-transform.md +0 -23
  157. package/skills/uipath-maestro-flow/references/bindings.md +0 -178
  158. package/skills/uipath-maestro-flow/references/branch.md +0 -18
  159. package/skills/uipath-maestro-flow/references/brownfield.md +0 -152
  160. package/skills/uipath-maestro-flow/references/connector-params.md +0 -624
  161. package/skills/uipath-maestro-flow/references/conversational.md +0 -77
  162. package/skills/uipath-maestro-flow/references/data-fabric.md +0 -268
  163. package/skills/uipath-maestro-flow/references/delay.md +0 -26
  164. package/skills/uipath-maestro-flow/references/diagnose.md +0 -141
  165. package/skills/uipath-maestro-flow/references/document-pipeline.md +0 -47
  166. package/skills/uipath-maestro-flow/references/error-handling.md +0 -75
  167. package/skills/uipath-maestro-flow/references/evaluate.md +0 -168
  168. package/skills/uipath-maestro-flow/references/event-trigger.md +0 -155
  169. package/skills/uipath-maestro-flow/references/form-trigger.md +0 -41
  170. package/skills/uipath-maestro-flow/references/hitl.md +0 -169
  171. package/skills/uipath-maestro-flow/references/http.md +0 -105
  172. package/skills/uipath-maestro-flow/references/inline-agent.md +0 -132
  173. package/skills/uipath-maestro-flow/references/ixp.md +0 -167
  174. package/skills/uipath-maestro-flow/references/loops.md +0 -77
  175. package/skills/uipath-maestro-flow/references/manual-trigger.md +0 -39
  176. package/skills/uipath-maestro-flow/references/operate.md +0 -204
  177. package/skills/uipath-maestro-flow/references/or-processes.md +0 -91
  178. package/skills/uipath-maestro-flow/references/parallel-merge.md +0 -21
  179. package/skills/uipath-maestro-flow/references/placeholder.md +0 -70
  180. package/skills/uipath-maestro-flow/references/published-function.md +0 -66
  181. package/skills/uipath-maestro-flow/references/queue.md +0 -53
  182. package/skills/uipath-maestro-flow/references/return.md +0 -20
  183. package/skills/uipath-maestro-flow/references/rpa-workflow.md +0 -27
  184. package/skills/uipath-maestro-flow/references/scheduled-trigger.md +0 -34
  185. package/skills/uipath-maestro-flow/references/script.md +0 -52
  186. package/skills/uipath-maestro-flow/references/subflow.md +0 -33
  187. package/skills/uipath-maestro-flow/references/summarize.md +0 -20
  188. package/skills/uipath-maestro-flow/references/switch.md +0 -20
  189. package/skills/uipath-maestro-flow/references/terminate.md +0 -22
  190. package/skills/uipath-maestro-flow/references/transform.md +0 -32
  191. package/skills/uipath-maestro-flow/references/voice.md +0 -70
@@ -1,77 +0,0 @@
1
- # Conversational
2
-
3
- *Exact signatures, fields, and defaults: `conversationTrigger()`, `waitForMessage()`, `sendMessage()`, `conversationContext()`, `conversationalAgent()`.*
4
-
5
- A chat-driven flow. A person opens a conversation; the flow waits for their
6
- message, answers it, and can post messages of its own. Every step is keyed by a
7
- `conversationId`, which the conversation TRIGGER publishes as
8
- `out('start', 'conversationId')`.
9
-
10
- ```ts
11
- export default flow('support-chat')
12
- .trigger(conversationTrigger())
13
- .step('listen', waitForMessage({ conversationId: out('start', 'conversationId') }))
14
- .step('reply', conversationalAgent({
15
- model: 'gpt-5.4',
16
- systemPrompt: 'You are a support agent. Be brief.',
17
- settings: { context: out('listen', 'conversationContext') },
18
- }))
19
- .step('closing', sendMessage({
20
- conversationId: out('start', 'conversationId'),
21
- exchangeId: out('listen', 'conversationContext.latestExchangeId'),
22
- content: 'Anything else I can help with?',
23
- }))
24
- .build();
25
- ```
26
-
27
- ## Conversations, exchanges, and messages
28
-
29
- Three nested things, and the field names follow them:
30
-
31
- - a **conversation** is the whole thread (`conversationId`);
32
- - an **exchange** is one user turn plus the answers to it (`exchangeId`);
33
- - a **message** is one utterance inside an exchange.
34
-
35
- `waitForMessage` returns the conversation CONTEXT, so the exchange to answer is
36
- a path inside it: `out('<waitStep>', 'conversationContext.latestExchangeId')`,
37
- and the transcript is `…conversationContext.messages`. (`out(step, path)`
38
- already inserts `.output` — do not write it again.)
39
-
40
- ## Waiting versus reading
41
-
42
- `waitForMessage` **suspends** the flow — it is a `bpmn:IntermediateCatchEvent`
43
- on `Maestro.ReceiveMessageEvent`, the same mechanism as `waitForEvent`, so the
44
- run parks until the person speaks. `conversationContext` does NOT wait: it reads
45
- the transcript so far and continues. Reach for the first when the flow's next
46
- step depends on what the person says next, the second when it only needs
47
- history. Both cap how much history they return (`numExchanges` /
48
- `exchangeLimit`, 1–40, platform default 20).
49
-
50
- ## Saying something: agent or flow
51
-
52
- `sendMessage` posts a message the FLOW composed — the role is always
53
- `assistant` and the content is Markdown (the node's only supported type), so
54
- neither is authored. `conversationalAgent` posts what a MODEL composed, reading
55
- the turn from `settings`:
56
-
57
- - `'simple'` mode (the default) takes ONE binding, `context`, and the platform
58
- derives the conversation id, exchange id, transcript and user settings from
59
- it. This is what you want almost always.
60
- - `'custom'` mode binds each field yourself, for a turn assembled from more
61
- than one source; `conversationId` is then required.
62
-
63
- Either way the four derived fields are what the runtime reads — the platform's
64
- own editor calls them the source of truth and its validator rejects a node
65
- without `conversationId`, so the SDK emits them from your `context` binding
66
- rather than leaving them out. The agent's reply is
67
- `out('<step>', 'uipath__agent_response_messages')`, and compile writes a stable
68
- `<source>/agent.json` sidecar beside the `.flow` as it does for `inlineAgent`.
69
-
70
- ## Evidence boundary
71
-
72
- The whole family is `AvailableOnTenant: false` today — the definitions are
73
- bundled from the workbench manifests, so a flow compiles and `validate`s
74
- offline, but nothing local starts a conversation or delivers a message. A green
75
- ladder proves the node types, the conversation/exchange wiring and the derived
76
- turn settings. A real thread, a real reply, and the agent's answer quality are
77
- platform evidence.
@@ -1,268 +0,0 @@
1
- # Data Fabric
2
-
3
- *Exact signatures, fields, and defaults: `dataFabricRead()`, `dataFabricCreate()`, `dataFabricUpdate()` and `dataFabricDelete()` for native CRUD, and `connector()` for the operations the native family still does not cover.*
4
-
5
- ## One product, two surfaces
6
-
7
- "Data Fabric" and "Data Service" are **the same product under two names**: the
8
- tenant lists connector key `uipath-uipath-dataservice` with the display name
9
- **UiPath Data Fabric**, and `uip df entities` manages the entities both surfaces
10
- read.
11
-
12
- The native `core.datafabric.*` family covers all four CRUD verbs, so **CRUD on
13
- one entity is native work** — one surface, no connection binding, no `prepare`
14
- step.
15
- Reach for the connector when the flow needs something the family does not have.
16
-
17
- | Operation | Surface |
18
- | --- | --- |
19
- | Query records, with filters, limit, paging and sort | `dataFabricRead({ entity, filters, resultMode, limit, skip, sort, fields })` |
20
- | Create a record | `dataFabricCreate({ entity, values })` |
21
- | Update a record | `dataFabricUpdate({ entity, record, set })` |
22
- | Delete a record | `dataFabricDelete({ entity, record })` |
23
- | Get a record by id | `dataFabricRead({ entity, filters: [{ field: 'Id', value: … }] })` |
24
- | Upload / download / delete a file record field | `connector('uipath-uipath-dataservice', '…-file-…-record-field', …)` |
25
- | Record Created / Record Updated events | `onEvent(…)` on the same connector |
26
-
27
- Only the bottom two are connector work. A flow that needs one of them straddles
28
- both surfaces — a connection binding, a second payload shape, two things to
29
- debug — so when that is the shape of the work, route the whole entity through
30
- the connector instead of mixing.
31
-
32
- Data Fabric **events** (Record Created / Record Updated on an entity) are
33
- Integration Service connector events on `uipath-uipath-dataservice`, not this
34
- node family: `onEvent(RecordCreated, { object: '<Entity>', … })`, with the
35
- entity named through `object`. See
36
- [`event-trigger.md`](event-trigger.md#generic-events-name-the-object).
37
-
38
- ## The four verbs
39
-
40
- ```ts
41
- .step('lookup', dataFabricRead({ entity: 'Invoices',
42
- filters: [
43
- { field: 'InvoiceId', value: input('invoiceId') },
44
- { field: 'Status', operator: '!=', value: 'Paid', or: true },
45
- ] }))
46
- .step('markPaid', dataFabricUpdate({ entity: 'Invoices',
47
- record: { fromRead: 'lookup' },
48
- set: { Status: 'Paid', PaidBy: js`$vars.lookup.output.Approver` } }))
49
- .step('logIt', dataFabricCreate({ entity: 'PaymentLog',
50
- values: { InvoiceId: input('invoiceId'), PaidOn: js`new Date().toISOString()` } }))
51
- .step('purge', dataFabricDelete({ entity: 'Drafts', record: { byId: input('draftId') } }))
52
- ```
53
-
54
- ## Filters and targeting
55
-
56
- A filter row is `{ field, operator?, value, or? }`. `operator` defaults to `'='`
57
- and is one of exactly ten spellings — `=` `!=` `>` `>=` `<` `<=` `contains`
58
- `starts with` `ends with` `in`. There is deliberately no `not in`, no
59
- `not contains`, and no null check: the serializer cannot emit them, and a filter
60
- it cannot emit takes the WHOLE query down rather than dropping one row.
61
- `in` is honoured only when `resultMode` is `'multiple'`.
62
-
63
- **The query model is disjunctive**, so `or: true` SPLITS the list rather than
64
- joining one row to the one before it. The whole query is `alt1 OR alt2 OR …`,
65
- and each alternative is an AND of its own rows; `or: true` opens a new
66
- alternative (and is ignored on the first row, which has nothing to split from):
67
-
68
- ```ts
69
- filters: [
70
- { field: 'Status', value: 'Open' },
71
- { field: 'Priority', value: 'High', or: true }, // Status
72
- { field: 'Region', value: 'EU' }, // OR (Priority AND Region)
73
- ]
74
- ```
75
-
76
- To express `(A OR B) AND C`, write it out as `(A AND C) OR (B AND C)` — the
77
- model has no other way to say it.
78
-
79
- A filter value must not be blank and must not reference `$self`: either one makes
80
- the serializer refuse the entire query, which leaves the step publishing nothing
81
- and strands every downstream `$vars` read of it. `check` rejects both.
82
-
83
- A filter on a choice-set column compares against the choice's numeric
84
- `numberId`, never its label — a label matches nothing, silently.
85
-
86
- `record` names the target row on **update and delete alike**, and takes exactly
87
- ONE of:
88
-
89
- - `{ byId: '<record id>' }` — a known record id, literal or expression;
90
- - `{ fromRead: '<step name>' }` — the record a preceding `dataFabricRead`
91
- step returned. It must be a genuinely SINGLE-record read: a multi-record query
92
- is refused as a write target, and the refusal is a no-op task, not an error —
93
- the flow validates, runs green, and writes nothing. `check` rejects a
94
- `fromRead` that names no read step (`DATAFABRIC_FROMREAD_UNKNOWN`) or names a
95
- `resultMode: 'multiple'` one (`DATAFABRIC_FROMREAD_MULTIPLE`).
96
-
97
- `set` (update) and `values` (create) map field names to values, literals or
98
- expressions.
99
- Both are rejected when empty, and `values` is rejected when every value is BLANK:
100
- a blank is omitted from an insert so the column default applies, so an all-blank
101
- create writes nothing and runs green. Fix that with a real value, never a
102
- placeholder to satisfy the rule.
103
-
104
- **Type each flow input by the field it fills.** `uip df entities get <id>
105
- --output json` gives each field's type at `Data.Fields[].FieldDataType.Name`; a
106
- value that arrives as a flow input takes the Flow type below, and reaches the
107
- step as `input('<name>')`:
108
-
109
- | Field type | Flow input |
110
- | --- | --- |
111
- | `STRING`, `MULTILINE_TEXT`, `UUID`, `DATE`, `DATETIME` | `types.string` |
112
- | `DECIMAL`, `INTEGER` | `types.number` |
113
- | `BOOLEAN` | `types.boolean` |
114
- | `FILE` | none — a file is not a create value; upload it with the connector's file-record-field operation (table above) |
115
-
116
- **System columns are never writable.** `Id`, `CreateTime`, `CreatedBy`,
117
- `UpdateTime`, `UpdatedBy` are assigned by Data Fabric; a write to one is rejected
118
- and the rejection is only logged, so the row comes back unchanged and the run
119
- goes green. `check` refuses them (`DATAFABRIC_SYSTEM_COLUMN`).
120
-
121
- A blank value means different things by verb: on create it is omitted so the
122
- default applies; on update it writes an explicit `null`, which a non-nullable
123
- column rejects. Check nullability with `uip df entities get`.
124
-
125
- ## Query-many needs `resultMode`, and `resultMode` needs 1.4
126
-
127
- `core.datafabric.read` started as read-ONE ("Read entity") and became
128
- read-one-or-query-many at **1.4** ("Query entity records").
129
- `resultMode: 'single'` publishes one record as the step's `output`;
130
- `resultMode: 'multiple'` publishes the matching records under `output.results`.
131
-
132
- The SDK still pins **1.0** as the version a plain `dataFabricRead()` emits, the
133
- same way every family here keeps its older default — so passing `resultMode` is
134
- what selects 1.4, exactly as a Quartz `every` selects the scheduled trigger's
135
- 1.2. Nothing else changes, and a read that wants one record can ignore all of
136
- this.
137
-
138
- ```ts
139
- .step('open', dataFabricRead({ entity: 'Invoices',
140
- filters: [{ field: 'Status', value: 'Open' }],
141
- resultMode: 'multiple' })) // → core.datafabric.read@1.4
142
- .loop('each', js`$vars.open.output.results`, (b) => b./* … */)
143
- ```
144
-
145
- `dataFabricRead({ resultMode }, { version: '1.0' })` is refused at compile time
146
- rather than emitting an input the 1.0 definition does not declare.
147
-
148
- ## Paging a list query
149
-
150
- `limit` is always applied — omitting it resolves to **100** — and **1000 is a
151
- hard ceiling**: a larger value truncates silently rather than erroring. Cover a
152
- bigger entity by paging with `skip`, and pair any limit with `sort` or the slice
153
- is arbitrary.
154
-
155
- ```ts
156
- .step('page1', dataFabricRead({ entity: 'Invoices', resultMode: 'multiple',
157
- limit: 1000, skip: 0, sort: { field: 'CreateTime', direction: 'desc' },
158
- fields: ['Id', 'Status'] }))
159
- ```
160
-
161
- The real audit columns are `Id`, `CreateTime`, `CreatedBy`, `UpdateTime`,
162
- `UpdatedBy` — there is no `CreatedAt`, and a sort on a column that does not exist
163
- is not caught by `validate`.
164
- `limit`, `skip`, `sort` and `fields` are list-query options: `check` refuses them
165
- on a single-record read.
166
-
167
- ## A folder-scoped entity needs its bindings
168
-
169
- A **tenant-scoped** entity needs nothing but `entity` — it serializes as a dotted
170
- literal.
171
-
172
- A **folder-scoped** one needs `folderKey` AND `resourceKey` together. With only
173
- the folder key the entity serializes as a source-org literal: it validates, it
174
- runs in this org, and it breaks on deploy to another. `check` refuses either half
175
- alone (`DATAFABRIC_FOLDER_NO_RESOURCE_KEY`).
176
-
177
- ```ts
178
- .step('read', dataFabricRead({ entity: 'Orders',
179
- folderKey: '<the entity\'s folderId>', resourceKey: '<solution resource key>' }))
180
- ```
181
-
182
- Supplying both emits the two `resource: 'Entity'` binding rows the platform
183
- matches on `propertyAttribute` (`name` and `folderKey` — never `folderPath`).
184
- Resolve the keys from the tenant:
185
-
186
- ```bash
187
- uip df entities list --include-folders --output json # folderId per entity
188
- uip solution resources list --kind Entity --output json # the resource key
189
- ```
190
-
191
- Nothing mints a resource key for a hand-authored flow. If you cannot resolve one,
192
- keep the entity tenant-scoped and omit both — a half-authored folder scope is
193
- worse than none.
194
-
195
- ## A delete publishes nothing
196
-
197
- `core.datafabric.delete` is the one verb of the family whose definition declares
198
- no outputs — the record is gone, so there is nothing to hand downstream.
199
- `$vars.<delete>.output` is undefined at run time, and `check` rejects the read
200
- (`DATAFABRIC_DELETE_HAS_NO_OUTPUT`).
201
- Take what the flow needs off the `dataFabricRead` step that FOUND the record,
202
- before the delete runs.
203
-
204
- ## The connector path, end to end
205
-
206
- For the operations still on the connector, an entity operation's body fields come
207
- from the entity, so the static library cannot carry them — `compile` refuses them
208
- as unknown inputs until you resolve the schema once:
209
-
210
- ```bash
211
- uip maestro registry prepare uipath-uipath-dataservice get-entity-record-by-id \
212
- -f entityName=ContractRegistry
213
- # → .flow-sdk/connectors-local/ + .flow-sdk/bindings.json, with the entity's own fields as inputs
214
- ```
215
-
216
- ```ts
217
- .step('byId', connector('uipath-uipath-dataservice', 'get-entity-record-by-id',
218
- { entityName: 'ContractRegistry', recordId: input('id') },
219
- { connection: 'dataservice', folder: 'shared' }))
220
- ```
221
-
222
- Full rules, including the parent-field (`GenerateSchema` over `entityName`)
223
- shape these operations use: [`connector-params.md`](connector-params.md).
224
-
225
- **Read the operation's own doc before guessing anything.** The connector library
226
- ships a Markdown page per operation, and an environment that stages a library
227
- points `$FLOW_SDK_LIBRARY_MD` at it (`uip maestro registry path --library-md --output plain`
228
- otherwise):
229
-
230
- ```bash
231
- sed -n '1,60p' "$FLOW_SDK_LIBRARY_MD/uipath-uipath-dataservice/create-entity-record@1.0.0.md"
232
- ```
233
-
234
- That page names the connector *UiPath Data Fabric*, gives the HTTP route
235
- (`POST /v2/{entityName}/CreateEntityRecord`), and prints the exact
236
- `prepare-connector … -f entityName=<value>` line to run — before any of it has to
237
- be inferred.
238
-
239
- ## Evidence boundary
240
-
241
- The entity name and field names are tenant data — copy them from the scenario
242
- or the tenant, never invent them.
243
-
244
- **Entity and column names are case-sensitive, and an unmatched column is dropped
245
- rather than rejected** — a wrong name yields a node that validates green and
246
- writes nothing. Nothing offline can tell a real column from a typo, so resolve
247
- them first:
248
-
249
- ```bash
250
- uip df entities list --native-only --include-folders --output json # writes need a NATIVE entity
251
- uip df entities get <entity-id> --output json # exact column names and types
252
- ```
253
-
254
- Two query options are documented by the platform but not applied by the
255
- converter the local engine runs: `limit`/`skip`/`sort` reach the file as
256
- `_recordLimit`/`_skip`/`_sort` and are read at run time, so `flow-debug` is not
257
- evidence either way for them.
258
-
259
- Offline `validate` proves only the emitted `entityConfig` SHAPE. It does not
260
- check whether a column exists, is writable, or has the type the value implies;
261
- whether the entity is native or federated; or whether a `byId` id matches
262
- anything. Every one of those validates clean and fails silently at run time, so
263
- green is not evidence here — the tenant is.
264
-
265
- A typed column also needs the canvas's `_outputSchema` snapshot to coerce
266
- values, and a dotted related path needs `_entityFields`. The SDK authors neither,
267
- so keep from-scratch nodes on the entity's own columns with string or expression
268
- values, and let the designer fill the snapshots in on first open.
@@ -1,26 +0,0 @@
1
- # Delay
2
-
3
- *Exact signatures, fields, and defaults: `delay()`.*
4
-
5
- Delay pauses the current path for a duration.
6
-
7
- Signature: `delay({ duration: string })` or `delay({ until: string })` —
8
- exactly one of the two arms.
9
-
10
- ```ts
11
- .step('cooldown', delay({ duration: 'PT30S' }))
12
- .step('embargo', delay({ until: '2026-09-01T09:00:00Z' }))
13
- .step('resumedAt', script({ code: 'return new Date().toISOString();' }))
14
- ```
15
-
16
- When the scenario needs a resume timestamp, compute it after the wait as shown.
17
- `until` is an ISO-8601 date-time and emits the node's absolute-date arm
18
- (`timerType: 'timeDate'`); an `until` in the past resumes immediately at run
19
- time, so compute future dates from the scenario, not from authoring day.
20
-
21
- Normal replay may skip real elapsed time. When timing is itself part of the
22
- requirement, use the real-time wait rung with a deliberately short fixture
23
- duration and measure before/after timestamps; product scheduling behavior still
24
- requires platform evidence.
25
-
26
- The duration is ISO-8601: `PT30S`, `PT15M`, `PT2H`, `P1D`, `P1W`.
@@ -1,141 +0,0 @@
1
- # Diagnose — why a run failed
2
-
3
- Triage order matters. Each step is cheaper and more specific than the next, and
4
- starting at the wrong end is how a diagnosis turns into twenty tool calls.
5
-
6
- 1. **The debug response you already have.** A faulted run carries its own cause.
7
- 2. **Incidents** on the instance.
8
- 3. **Runtime variables** at the point of failure.
9
- 4. **The deployed artifact** — what is actually on the tenant, not what is on disk.
10
- 5. **Traces**, last. They are the whole execution timeline.
11
-
12
- Never start at traces, and never re-run `flow debug` to "get a better look" — a
13
- re-run executes the flow again for real and returns the same information the
14
- first one did.
15
-
16
- ## Step 0 — read the cause in the output you already have
17
-
18
- `Data.finalStatus: "Faulted"` means the response in hand holds the reason. On a
19
- faulted run the CLI ignores `--output-filter` and prints the whole envelope, so
20
- redirect it and search the file rather than re-running:
21
-
22
- ```bash
23
- UIP_LOG_LEVEL=info uip maestro flow debug <project-dir> --output json > /tmp/flow-debug.json
24
- ```
25
-
26
- Look for the faulted element and its message. The node id in the fault maps
27
- back to the `.step('<id>', …)` that produced it, so the fix is usually a source
28
- edit rather than a platform question.
29
-
30
- ## Incidents, variables, and the deployed artifact
31
-
32
- ```bash
33
- # what went wrong
34
- uip maestro flow instance incidents <INSTANCE_ID> -f <FOLDER_KEY> --output json
35
- uip maestro flow incident get <INCIDENT_ID> -f <FOLDER_KEY> --output json
36
- uip maestro flow incident summary --output json # across instances
37
-
38
- # state at the point of failure
39
- uip maestro flow instance variables <INSTANCE_ID> -f <FOLDER_KEY> --output json
40
- uip maestro flow instance variables <INSTANCE_ID> -f <FOLDER_KEY> \
41
- --parent-element-id <ELEMENT_ID> --output json # scoped to one element
42
- uip maestro flow instance element-executions <INSTANCE_ID> -f <FOLDER_KEY> --output json
43
- uip maestro flow instance cursors <INSTANCE_ID> -f <FOLDER_KEY> --output json
44
-
45
- # what is deployed, and which instances exist
46
- uip maestro flow instance asset <INSTANCE_ID> -f <FOLDER_KEY> --output json
47
- uip maestro flow instance list -f <FOLDER_KEY> --output json
48
- uip maestro flow instance get <INSTANCE_ID> -f <FOLDER_KEY> --output json
49
-
50
- # last resort
51
- uip maestro flow job status <job-key> --output json
52
- uip maestro flow job traces <job-key> --output json
53
- ```
54
-
55
- All of these need `uip login`. Every `instance` command and `incident get` also
56
- needs `--folder-key` (`-f`) or it is rejected before reaching the API. Get the key from
57
- `uip or folders list --output json`, or from the job or process context.
58
-
59
- **Use these commands, never the underlying APIs.** The CLI applies the tenant
60
- and folder resolution the raw endpoints do not, so a direct call that appears to
61
- work is reading a different scope from the one the run used.
62
-
63
- When local and deployed disagree, the deployed artifact is the one that ran.
64
- A flow edited but not re-uploaded is the most common explanation for "I fixed
65
- that already".
66
-
67
- ## Failure modes that survive the SDK path
68
-
69
- The builder makes several classic `.flow` defects unreachable — see the next
70
- section. These are the ones it does NOT:
71
-
72
- **An expression that is really a literal.** The builder does not force a `$vars`
73
- reference through `js\`…\`` or `out()`. A plain string containing
74
- `$vars.step.output` compiles to a bare literal with no `=js:` prefix, `check`
75
- reports no issues, and the node receives the text `"$vars.step.output"` at run
76
- time instead of the value. Symptom: a downstream node acting on a string that
77
- looks like an expression. Fix: `out('step')` or `` js`${out('step')}` ``.
78
-
79
- **A HITL outcome with no route.** More than one outcome routes per outcome by
80
- default, and an outcome with no arm leaves the run stalled when a reviewer picks
81
- it. `check` warns `HITL_OUTCOME_UNROUTED`; the warning is the diagnosis. Fix:
82
- `.stepSwitch` with an arm per outcome.
83
-
84
- **`Completed` with the work not done.** A node with error handling enabled and
85
- no handler, or an error edge routed back into the happy path, lets a failed step
86
- report success upward. Symptom: green run, absent side effect. Read the node's
87
- own status, not the run's.
88
-
89
- **A reused connection or resource key.** A key copied from another flow is
90
- well formed, so `check` and `validate` both accept it and the node faults at run
91
- time against a connection this tenant does not have. Read keys from
92
- `registry list --local` or the generated resource file, never from another
93
- project.
94
-
95
- **A single-nested project that upload rejects.** `uip maestro flow init` with
96
- `--skip-solution-registration` opts out of auto-scaffold and registration and
97
- leaves `<Project>/<Project>.flow` where `<Solution>/<Project>/<Project>.flow` is
98
- required; `Data.SolutionRegistration.Status` comes back `OptedOut` or
99
- `NotInSolution`, and upload and packaging both fail on structure. Without the
100
- flag, `flow init` outside a solution scaffolds and registers on its own, so this
101
- is opt-in rather than accidental. Fix by deleting the partial scaffold and
102
- running `uip solution init` then `flow init` from inside the solution; add
103
- `uip solution projects add` only if `Status` is not `Registered`. Carry
104
- `--automate` on the rebuild if the original was a Maestro Automate project — a
105
- `.maestro_automate` file in the project root says it was, and rebuilding without
106
- the flag silently returns a plain Flow.
107
-
108
- **Misshapen nodes on the canvas.** `compile` writes a placeholder
109
- `ui.position` on each node — all of them on one row — and no top-level `layout`
110
- block, which is what the canvas renders from. Symptom: the flow behaves
111
- correctly and is unreadable, a switch's arms strung out in a line instead of
112
- side by side. This is not a run-time fault and no check reports it — `validate`
113
- passes, because layout is not an authoring concern. Fix:
114
- `uip maestro flow format <Name>.flow`, which is owed before an upload, a debug,
115
- or anyone opening the project in a designer — see
116
- [`operate.md`](operate.md#lay-out-the-emitted-flow-first).
117
-
118
- **Green `validate`, faulted `debug`.** Structural correctness and runtime
119
- correctness are different claims. `validate` proves the emitted `.flow` is well
120
- formed; only a run proves the tenant resolves what it references. Start at
121
- step 0.
122
-
123
- ## Failure modes the builder removes
124
-
125
- Do not spend triage on these — the compiler emits the structure that used to be
126
- missing. Verified against the SDK rather than assumed:
127
-
128
- | Classic `.flow` defect | Why it cannot happen here |
129
- | --- | --- |
130
- | `variables.nodes[]` missing, so `$vars.X.output` is undefined downstream | `compile` emits the node variable declarations unasked — a four-step flow gets eight entries |
131
- | `bindings[]` missing on a resource node, giving "Folder does not exist or the user does not have access" | `compile` derives the bindings from the node spec — an `agent(…)` step emits its `name` and `folderPath` bindings on its own |
132
-
133
- A defect in this table showing up in a real run means the artifact was
134
- hand-edited after `compile`, which is its own answer.
135
-
136
- ## Evidence boundary
137
-
138
- A diagnosis is only as good as what was read. Name the artifact the conclusion
139
- came from — the debug envelope, the incident, the deployed flow — and say when a
140
- cause is inferred rather than observed. "The connector is misconfigured" read
141
- off a timeout is a guess; the same claim read off an incident's message is not.
@@ -1,47 +0,0 @@
1
- # Document classify and Dynamic Extract
2
-
3
- *Exact signatures, fields, and defaults: `documentClassify()` and `dynamicExtract()`.*
4
-
5
- Two document steps that need no published IxP project: classification
6
- (`uipath.document.classify`) labels a document, and Dynamic Extract
7
- (`uipath.ixp.extract-document-builder`) pulls fields against a schema you
8
- author INLINE. For a published project's trained fields, use `ixpExtract`
9
- ([ixp.md](ixp.md)) instead.
10
-
11
- Signatures: `documentClassify({ fileRef, pageRange?, splitPages?, modelConfig? })`;
12
- `dynamicExtract({ fileRef, schema, model, pageRange?, modelConfig? })`.
13
-
14
- ```ts
15
- .input({ file: types.file })
16
- .step('classify', documentClassify({ fileRef: input('file'), splitPages: true }))
17
- .step('extract', dynamicExtract({
18
- fileRef: input('file'),
19
- schema: { type: 'object', properties: {
20
- invoiceTotal: { type: 'string', description: 'Grand total' } } },
21
- model: { modelName: 'invoiceixp-cef0d447-ixp',
22
- folderKey: 'c4359cde-55f0-4f0e-9322-c6cdce74ab4c' },
23
- }))
24
- .step('total', script({ code: 'return $vars.extract.output.ExtractionResult;' }))
25
- ```
26
-
27
- ## The model identity
28
-
29
- Dynamic Extract authors its SCHEMA inline, but execution still runs against a
30
- model deployment: `model.modelName` and `model.folderKey` are REQUIRED (the
31
- platform validator rejects the node without them), with optional `projectId`,
32
- `projectName`, `folderName`, and `versionTag`. Copy them from the tenant —
33
- never construct them.
34
-
35
- ## Schema and outputs
36
-
37
- `schema` is a JSON-Schema object (`type: 'object'` with `properties`, each
38
- usually carrying a `description` the model reads). It is emitted as the node's
39
- `schemaDocument`. Classification lands at `out('classify', ...)`; extraction
40
- results at `out('extract', 'ExtractionResult')`.
41
-
42
- ## Evidence boundary
43
-
44
- Both calls hit real document-understanding services — no local rung runs a
45
- model. Offline `validate` proves the emitted shape (fileRef wiring, schema,
46
- model identity, the classify `success` port); classification quality and
47
- extraction values are platform evidence.
@@ -1,75 +0,0 @@
1
- # Error Handling
2
-
3
- An error handler is a separate path from the immediately preceding action.
4
-
5
- Signature: `.step(name, action).onError(handler => ...)`.
6
- Read the failure with `h.err(field)` — or `err(step, field)` if you prefer to name the step — where field is one of `code`, `message`, `detail`, `category`, `status` (plus `response` and `element`, present at run time though undeclared).
7
- A handler may `.return(...)`, `.terminate(...)`, or `.stepToRef(target)`.
8
-
9
- ```ts
10
- .step('fetch', http({ url, managed: true }))
11
- .onError((h) => h.step('recover', script({ code: 'return "cached";' }))
12
- .stepToRef('useValue'))
13
- .step('useValue', script({ code: 'return "done";' }))
14
- ```
15
-
16
- ## Reading the failure
17
-
18
- `err()` writes ONE shape — `$vars.<step>.error.<field>` — and the compiler resolves where that family actually publishes the envelope.
19
- Do not hand-write either prefix, and do not read the failed step's `out(...)` inside its own handler: that path runs because the step failed, so its success output was never written (`ERROR_ENVELOPE_VIA_OUTPUT`).
20
-
21
- Which variable holds the envelope is a per-node-family runtime fact, measured one debug run per family (2026-09-10):
22
-
23
- | family | envelope in | `<step>.error` is |
24
- | --- | --- | --- |
25
- | connector (every one) | `<step>.error` | the envelope |
26
- | `core.action.script` | `<step>.error` | the envelope |
27
- | `uipath.pattern.deep-rag` | `<step>.error` | the envelope |
28
- | `core.subflow` | `<step>.error` | the envelope |
29
- | `core.action.queue.create` | `<step>.error` | the envelope |
30
- | `core.action.http.v2` (`managed: true`) | `<step>.output` | the boolean `true` |
31
- | `core.action.http` (`managed: false`) | nowhere | the boolean `true` |
32
-
33
- `serialize` rewrites the read for the exception families, so authored source stays uniform and a family moving is a table edit rather than a fleet-wide rewrite.
34
- A bare `err(step)` is the did-this-fail test and is never rewritten: it reads truthy on every family, the envelope object included.
35
-
36
- Plain `http({ managed: false })` publishes no envelope in any version — 1.0.0 and the 1.3 `uip maestro flow migrate` upgrades it to both leave `<step>.output` null — so `check` refuses a handler there (`HTTP_ONERROR_V1`) instead of emitting a read that resolves to nothing.
37
- That node is also gone from the tenant registry, which serves only `core.action.http.v2`; `check` says so (`HTTP_V1_RETIRED`).
38
- Moving to the managed node is a behaviour change, not a rename: a non-2xx stops arriving on the success path with `statusCode` and fails the step instead, so a status branch becomes a handler reading `err(step, 'status')`.
39
-
40
- A `.loop()` container CAN carry a handler: `.onError()` after `.loop(...)` wires the container's own error port, and a body step's failure routes to it — measured, the container's envelope carries the body's message in `detail` and the failing body step's id in `element`, and the instance completes instead of faulting. Read it the usual way, `h.err('detail')`.
41
-
42
- A `.doWhile()` cannot, and the reason is the handle rather than the variable: `core.logic.dowhile@1.0` declares an error variable but its handles are input, success, start, continue and break, so an edge would leave a handle the node does not have — the shape that fails product validate with "the current manifest does not declare that handle". Handle the failure inside the body, on the step that can fail. The builder refuses it by name.
43
-
44
- `.onError(...)` is the `error` port case of `.stepToList(port, handler)`, which
45
- runs a path from any named port. When the failure needs no work of its own, name
46
- the target directly — `.stepToRef('error', 'refund')` — which is a SIDE EXIT: the
47
- success path continues, so chaining carries on after it.
48
-
49
- A `.stepToRef(target)` with no port leaves the default `output` port and HANDS THE
50
- PATH OFF, so nothing may follow it in that list. The target may sit anywhere in the
51
- same scope, including BACKWARD of the step that names it — Flow JSON can express
52
- that, so this can author it.
53
-
54
- ## Choosing the path
55
-
56
- Do not add recovery merely because an error port exists. Decide whether the
57
- business operation should fail loud, return an alternate answer, stop all work,
58
- or compensate and rejoin. An exhausted handler ends separately; use
59
- `.stepToRef(...)` only when the failure path should deliberately resume shared
60
- success-path work.
61
-
62
- Two limits `check` enforces on a ref, and one it only warns about. It refuses an
63
- unknown target, a target inside another port's path, and a target inside a LOOP
64
- BODY — a loop reads `currentItem` / `currentIteration` per iteration, and an edge
65
- arriving from outside carries no iteration. It WARNS when a ref leaves a loop body
66
- (a break, which Flow has no node for) or crosses a parallel arm boundary (the Merge
67
- waits for every branch it forked). Those are best effort: verify them with
68
- `uip maestro flow validate`.
69
-
70
- ## Evidence
71
-
72
- Test both sides. The failure case should prove the handler receives the expected
73
- service error and reaches its intended terminal or ref behavior. The success
74
- case should prove normal continuation still bypasses the handler. A single green
75
- case cannot establish both paths.