Repository navigation
docs(uipath-maestro-flow): debug envelope and limits, entry-point roots, agent HTTP tool resource, Studio Web connector steps, Data Fabric long text - #3783
Conversation
…ot, debug envelope incidents, agent tool kinds, Studio Web connector steps, Data Fabric long-text reads
|
Claude finished @danmunteanu1's task in 2m 58s —— View job PR Review: docs(uipath-maestro-flow)
SummaryDocuments 12 previously undocumented runtime behaviors discovered while building flows from genomes: Change-by-Change Review1.
|
| Area | Status | Notes |
|---|---|---|
| Frontmatter | OK | No frontmatter changes in this PR |
| E2E Tests | OK | No new CLI workflows or commands; behavioral documentation additions — existing tests still cover the skill |
| Skill Body | OK | Single-line addition to SKILL.md is accurate and prescriptive |
| References & Assets | OK | All 12 reference files follow conventions, all 7 cross-reference links resolve, heading hierarchy consistent, no duplication |
| Repo Hygiene | OK | All changes scoped to skills/uipath-maestro-flow/, no secrets or personal paths, no cross-skill references |
Issues for Manual Review
- Factual correction in CLI-LOOP.md: The previous version stated "There is no
incidentsin this envelope" — now saysData.incidentsis filled for a faulted run. This is a significant behavioral correction that should be verified against actual CLI output from a faulted debug run. - Data Fabric 10,000-character truncation: The long-text field truncation limit and the
...[Truncated]marker are domain-specific claims that can only be verified against the product. - Exit code
0x33for RPA headless debug: Domain-specific claim about theSignalr agent missing protocol versionsfailure. - Provisioning error
2106: TheSequence contains no matching elementmessage for unresolvable process/connection nodes is a runtime-specific claim. - HTTP tool
resource.jsontemplate: The JSON structure, field mappings, andargumentPropertiesformat can only be verified by runningcompileand inspecting the emitted artifact.
Conclusion
Clean PR. All 13 changed files follow repo conventions — consistent placeholder style, prescriptive language, correct heading hierarchy, and proper reference pointer discipline across 7 cross-file links. The changes document undocumented runtime behaviors with concrete error codes, exit codes, and workarounds. No issues found.
… SDK 6.16.3; a failing step's own updates apply for a script step only
danmunteanu1
left a comment
There was a problem hiding this comment.
Notes on text that changes once a reported defect is fixed.
| giving an agent a tool; fixing nothing gives the model no constraints. Fix what | ||
| the scenario pins and leave the rest. | ||
|
|
||
| **The HTTP tool needs a resource file you write.** `compile` writes no |
There was a problem hiding this comment.
Goes when compile writes the HTTP tool's resource.json: UiPath/flow-builder-sdk#935.
| wrapper. One call is one page; use the operation's filtering/paging inputs when | ||
| the business operation needs a narrower or later page. | ||
|
|
||
| ## Studio Web and compiled connector steps |
There was a problem hiding this comment.
Section goes when compile emits configuration.fieldsContainer, so Studio Web shows the values and a save keeps them: UiPath/flow-builder-sdk#936.
| - **`Debug polling timed out after <N>s` is not a failure.** The run continues | ||
| server-side. Take `instanceId` from stderr and poll | ||
| `uip maestro flow debug-instance status <INSTANCE_ID> --output json`. | ||
| - **Only the default root runs.** Debug starts the root `.trigger()` / `.input()` |
There was a problem hiding this comment.
The scratch-copy procedure goes when flow debug takes the entry point to start: UiPath/cli#4811.
| trigger, inputs and prefix, delete the copy afterwards, and report the run as | ||
| the copy's. | ||
| - **An RPA step does not run under a headless debug** ([rpa-workflow.md](rpa-workflow.md#evidence-boundary)). | ||
| - **Every process and connection node must resolve.** A node bound to a |
There was a problem hiding this comment.
Changes when flow debug names the unresolved node and binding before upload (UiPath/cli#4831) and validate reports an in-solution call with no matching process resource (UiPath/cli#4837): "while check and validate pass" then no longer holds.
| The JSON envelope has top-level `Result`; a successful validation also reports | ||
| `Data.Status: "Valid"` and may carry `Data.Warnings`. Treat warnings as failures | ||
| except for the reviewed shared-connection advisory. Preserve any exception's | ||
| except for the reviewed shared-connection advisory and the expected error-envelope |
There was a problem hiding this comment.
This exception goes, with the EXPRESSION_DIAGNOSTIC paragraph in error-handling.md, when the validator types element, response and managed-HTTP step reads. Owner: the Flow expression model in UiPath/flow-workbench, which has no issue tracker; not filed yet.
| `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. | ||
| A bare `err(step)` is the did-this-fail test and is never rewritten: it reads truthy on every family, the envelope object included. | ||
|
|
||
| `flow validate` warns `EXPRESSION_DIAGNOSTIC` on reads the runtime does fill: `element` and `response`, which no manifest declares, and every field read from a managed HTTP step, whose rewritten `<step>.output` read the validator types only as `{ error }`. These warnings are expected; review each against this table rather than rewriting the read. |
There was a problem hiding this comment.
Goes with the CLI-LOOP.md exception when the validator types these reads (Flow expression model, not filed yet).
|
|
||
| Signature: `.step(name, action).onError(handler => ...)`. | ||
| 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). | ||
| 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; `element` is the failing step's canvas label, which equals its id only when the step has no `label`). |
There was a problem hiding this comment.
Redundant once the err() docs say element is the canvas label: UiPath/flow-builder-sdk#952. The runtime fact stays.
| Take what the flow needs off the `dataFabricRead` step that FOUND the record, | ||
| before the delete runs. | ||
|
|
||
| ## A long-text field reads back cut |
There was a problem hiding this comment.
This section, its table row and the "Still connector-only" clause go when read-one by Id returns the whole field, or change if a cut value gets a marker field: UiPath/flow-builder-sdk#954 (Data Service side not filed yet).
| values. Pick the interval from the business requirement rather than from what | ||
| is convenient to test. | ||
|
|
||
| `every` is the trigger's only field: there is no time-zone setting. A schedule |
There was a problem hiding this comment.
Changes to setting the trigger's time zone if one is added (Flow product feature request, not filed yet).
| The two combine: `shared` copies what is the same on every root, and a prefix | ||
| reshapes the rest. | ||
|
|
||
| `flow debug` runs only the default root |
There was a problem hiding this comment.
Goes with the operate.md bullet when UiPath/cli#4811 lands.
rockymadden
left a comment
There was a problem hiding this comment.
🔴 Changes requested. The HTTP tool template writes a fixed method even when the model is meant to choose it, and the debug field list drops folderKey, which the CLI still returns.
📝 What
- Split from #3460. Adds lessons from building flows from genomes to the
uipath-maestro-flowreferences: debug output (incidents,variablesError), debug limits, a hand-written HTTP toolresource.json, connector steps losing values in Studio Web, Data Fabric long-text cuts, schedule time zones, and theflow initnaming rule.
🔍 Overall findings
- 🟡 minor: the description doesn't match the diff.
- It says a form trigger "works only as the default root". 35ef69f dropped that;
manual-trigger.mdnow saysflow debugruns only the default root. - It says a step with a handler "still applies its
{ updates }". The doc says only a script step does. - Fix: update the description.
- It says a form trigger "works only as the default root". 35ef69f dropped that;
- 🟡 minor: these are runtime measurements I could not verify from source: exit
0x33, error2106, Studio Web20042/20021,elementholding the step label, a failing script step still applying its updates, and the hand-written HTTPresource.jsonworking at run time.- Fix: confirm each was seen on a live run; cut any that wasn't.
Out of scope, untagged: flow-builder-sdk keeps copies of these files under website/reference/ (loops.md, CLI-LOOP.md, error-handling.md, data-fabric.md) that already differ from the skill. This PR widens the gap.
tl;dr
Most claims hold against CLI and SDK source. Two are wrong (HTTP template method, missing folderKey), one exemption is too broad, one Data Fabric snippet is a duplicate.
| `display.label`, `description` its `inputs.description`, `canvasNodeId` its | ||
| node id, and each schema property's `description` that field's `promptValue`. | ||
| 3. Give `argumentProperties` one entry per field the scenario fixed (mode other | ||
| than `prompt`), valued with its `textValue`. The template fixes `method`. |
There was a problem hiding this comment.
🟠 major: method defaults to prompt mode on the node (SDK core-definitions.json, builtin.httprequest defaults), so the model fills it.
- The template always writes
$['method']as a static value (line 96), and "The template fixesmethod" tells the agent to keep it. - When the scenario didn't fix
method, the file pins it to""and the model can't set it.
💡 Fix: "The method entry is an example; drop it unless the scenario fixed method." Or ship the template with empty argumentProperties.
| giving an agent a tool; fixing nothing gives the model no constraints. Fix what | ||
| the scenario pins and leave the rest. | ||
|
|
||
| **The HTTP tool needs a resource file you write.** `compile` writes no |
There was a problem hiding this comment.
🟡 minor: the SDK skips this file on purpose: "not measured, so not written" (serialize.ts:1085). This is a 56-line manual workaround the agent repeats after every compile.
💡 Fix: open a flow-builder-sdk issue for emitting it and link it here, so the block can be removed later.
| `solutionId`, `variables` and `elementExecutions` — an `incidents:incidents` | ||
| projection silently yields `null`. Incidents come from the separate | ||
| `debug-instance incidents` call below, keyed by the `instanceId` you just read. | ||
| **`incidents` is filled only for a faulted run.** `Data` carries `finalStatus`, |
There was a problem hiding this comment.
🟡 minor: the new Data list drops folderKey. The CLI still sets it on every completed run (cli debug.ts:1023, flow-debug-service.ts:1620). An agent reading this list will think it's gone.
💡 Fix: put folderKey back.
| `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. | ||
| A bare `err(step)` is the did-this-fail test and is never rewritten: it reads truthy on every family, the envelope object included. | ||
|
|
||
| `flow validate` warns `EXPRESSION_DIAGNOSTIC` on reads the runtime does fill: `element` and `response`, which no manifest declares, and every field read from a managed HTTP step, whose rewritten `<step>.output` read the validator types only as `{ error }`. These warnings are expected; review each against this table rather than rewriting the read. |
There was a problem hiding this comment.
🟠 major: "every field read from a managed HTTP step" is a blanket exemption.
author.md:52says anEXPRESSION_DIAGNOSTICmeans the read returnsundefinedat run time, so a typo on an HTTP read now gets waved through.- It contradicts
CLI-LOOP.md's own rule against broadening the allowlist.
💡 Fix: limit it to err(<httpStep>, …) / h.err(…) reads. Example: err('fetch', 'status') expected, $vars.fetch.output.bdy not.
| .step('full', connector('uipath-uipath-dataservice', 'get-entity-record-by-id', | ||
| { entityName: 'Documents', recordId: input('recordId') }, | ||
| { connection: 'dataservice', folder: 'shared' })) | ||
| // $vars.full.output.document holds the whole text |
There was a problem hiding this comment.
🟡 minor: this repeats the get-entity-record-by-id snippet already in § "The connector path, end to end", ~20 lines down, and skips the registry prepare step that section requires. output.document reads like a fixed key, but it's the field name.
💡 Fix: link to the existing section and write $vars.full.output.<field>.
| ## A long-text field reads back cut | ||
|
|
||
| `dataFabricCreate` stores a long-text (`MULTILINE_MAX`) field whole, but every | ||
| native read returns its first 10,000 characters with `...[Truncated]` appended: |
There was a problem hiding this comment.
🟡 minor: "every native read returns its first 10,000 characters with ...[Truncated]" conflicts with uipath-platform entity-schema.md:83 and uipath-coded-apps data-fabric.md:23, which say some tenants return a HasValue=true Length=N marker instead.
💡 Fix: "returns a preview (the first 10,000 characters + ...[Truncated], or a HasValue=true Length=N marker, depending on the tenant)".
| **Run the SDK verbs (`flow check`, `compile`, `decompile`, `merge`, `registry pull`/`prepare`, `node .flow-sdk/*.pipeline.mjs`) from the project folder `<Solution>/<Name>/`**, as `( cd <Solution>/<Name> && … )` when your shell does not keep its directory between commands; every `.flow-sdk/` path in this guide and its references is relative to that folder. Everything else runs from the workspace root. | ||
| Scaffold the project first, seed the source from it, then emit back into it — `compile -o` is the authority over where the emitted file is written. | ||
| `<Solution>` and `<Name>` are the request's own names, used verbatim: a request that gives one name for both ("inside a solution of the same name") uses it for both, and a request that names only the Flow uses `<Name>` for both. | ||
| `<Solution>` and `<Name>` are the request's own names, used verbatim: a request that gives one name for both ("inside a solution of the same name") uses it for both, and a request that names only the Flow uses `<Name>` for both. `flow init` accepts only letters, numbers, `_` and `-` in `<Name>`, so join its words and drop any other character (`Headcount report form` → `HeadcountReportForm`); `<Solution>` keeps its spaces. |
There was a problem hiding this comment.
🟡 minor: "used verbatim" plus cleaning <Name> conflicts with "a request that names only the Flow uses <Name> for both": raw or cleaned name for the solution? The scaffold block also runs uip solution init <Solution> unquoted, which breaks on spaces.
💡 Fix: "the solution takes the raw name", and uip solution init "<Solution>".
| dedicated step whose contract supplies that aggregate. | ||
| Keep per-item dispatch and decisions in the body. A value the steps after the | ||
| loop need is written to a `.var()` from a body step with `{ updates }`, as | ||
| the last example below shows. |
There was a problem hiding this comment.
🟡 minor: "the last example below" is the .doWhile() pagination example, not a .loop().
💡 Fix: "as the scan example in Loop options shows".
|
|
||
| The step starts an Orchestrator job, and the robot that takes it decides the | ||
| project type: serverless cloud robots run only background, cross-platform | ||
| projects (vendor documentation), and jobs a Flow starts have run on them even |
There was a problem hiding this comment.
🟡 minor: "(vendor documentation)" has no link, and "jobs a Flow starts have run on them even where…" is a story, not an instruction. Line 40's attachment-reference sentence repeats operate.md:138.
💡 Fix: link the serverless robot doc, cut the story, drop the repeated sentence.
| `every` is the trigger's only field: there is no time-zone setting. A schedule | ||
| fixed to local hours (a run at 06:00 local time through daylight-saving | ||
| changes) has no setting here; record the time zone the requirement uses and | ||
| confirm the deployed trigger's run times. |
There was a problem hiding this comment.
🟡 minor: "confirm the deployed trigger's run times" doesn't say how, and the useful fact, which zone the schedule runs in (UTC or tenant), is missing.
💡 Fix: name the zone and the command that shows the deployed trigger's next run.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Several instructions are conflicting or incomplete, including the agent resource template, parallel-loop updates, warning policy, and Data Fabric preview handling.
Review effort: Balanced
Findings: 1
Open (7)
Treat preview values as read-only and prohibit update reuse · New Quote solution placeholders in scaffold commands · New Define distinct solution and Flow name derivations · New Align lifecycle and reference contracts for error-envelope warnings · New Include required null referenceKey in built-in tool resources · New Prevent concurrent shared-variable writes in parallel loops · New Clarify immutable project type and runtime compatibility constraints · New
What changed in this PR
Refines Maestro Flow guidance based on observed runtime and Studio Web behavior.
Changes:
- Documents debug, trigger, file-input, RPA, loop, and error-handling behavior.
- Adds connector, agent HTTP-tool, and Data Fabric limitations.
- Clarifies project naming and scheduling constraints.
| File | Description |
|---|---|
SKILL.md |
Documents Flow naming restrictions. |
scheduled-trigger.md |
Clarifies time-zone limitations. |
rpa-workflow.md |
Documents runtime and file arguments. |
operate.md |
Expands debug constraints and attachments. |
manual-trigger.md |
Notes default-root debugging. |
loops.md |
Adds variable-update guidance. |
inline-agent.md |
Links additional tool guidance. |
form-trigger.md |
Clarifies file upload fields. |
error-handling.md |
Documents envelopes and failed-step updates. |
data-fabric.md |
Adds long-text limitations and workaround. |
connector-params.md |
Documents Studio Web round-trip behavior. |
CLI-LOOP.md |
Updates debug-envelope semantics. |
agent-resources.md |
Adds HTTP-tool resource instructions. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| `dataFabricCreate` stores a long-text (`MULTILINE_MAX`) field whole, but every | ||
| native read returns its first 10,000 characters with `...[Truncated]` appended: | ||
| the query-many read, the read-one with an `Id` filter (it compiles to a query), | ||
| and the create step's own output. Nothing else marks the cut — `check`, | ||
| `validate` and the run all pass, and the next step works on the cut text. |
| **Run the SDK verbs (`flow check`, `compile`, `decompile`, `merge`, `registry pull`/`prepare`, `node .flow-sdk/*.pipeline.mjs`) from the project folder `<Solution>/<Name>/`**, as `( cd <Solution>/<Name> && … )` when your shell does not keep its directory between commands; every `.flow-sdk/` path in this guide and its references is relative to that folder. Everything else runs from the workspace root. | ||
| Scaffold the project first, seed the source from it, then emit back into it — `compile -o` is the authority over where the emitted file is written. | ||
| `<Solution>` and `<Name>` are the request's own names, used verbatim: a request that gives one name for both ("inside a solution of the same name") uses it for both, and a request that names only the Flow uses `<Name>` for both. | ||
| `<Solution>` and `<Name>` are the request's own names, used verbatim: a request that gives one name for both ("inside a solution of the same name") uses it for both, and a request that names only the Flow uses `<Name>` for both. `flow init` accepts only letters, numbers, `_` and `-` in `<Name>`, so join its words and drop any other character (`Headcount report form` → `HeadcountReportForm`); `<Solution>` keeps its spaces. |
| **Run the SDK verbs (`flow check`, `compile`, `decompile`, `merge`, `registry pull`/`prepare`, `node .flow-sdk/*.pipeline.mjs`) from the project folder `<Solution>/<Name>/`**, as `( cd <Solution>/<Name> && … )` when your shell does not keep its directory between commands; every `.flow-sdk/` path in this guide and its references is relative to that folder. Everything else runs from the workspace root. | ||
| Scaffold the project first, seed the source from it, then emit back into it — `compile -o` is the authority over where the emitted file is written. | ||
| `<Solution>` and `<Name>` are the request's own names, used verbatim: a request that gives one name for both ("inside a solution of the same name") uses it for both, and a request that names only the Flow uses `<Name>` for both. | ||
| `<Solution>` and `<Name>` are the request's own names, used verbatim: a request that gives one name for both ("inside a solution of the same name") uses it for both, and a request that names only the Flow uses `<Name>` for both. `flow init` accepts only letters, numbers, `_` and `-` in `<Name>`, so join its words and drop any other character (`Headcount report form` → `HeadcountReportForm`); `<Solution>` keeps its spaces. |
| `Data.Status: "Valid"` and may carry `Data.Warnings`. Treat warnings as failures | ||
| except for the reviewed shared-connection advisory. Preserve any exception's | ||
| except for the reviewed shared-connection advisory and the expected error-envelope | ||
| diagnostics ([`error-handling.md`](error-handling.md#reading-the-failure)). Preserve any exception's |
| "$resourceType": "tool", | ||
| "id": "<TOOL_SOURCE>", | ||
| "name": "<TOOL_LABEL>", | ||
| "description": "<TOOL_DESCRIPTION>", | ||
| "type": "internal", |
| Keep per-item dispatch and decisions in the body. A value the steps after the | ||
| loop need is written to a `.var()` from a body step with `{ updates }`, as | ||
| the last example below shows. |
| The step starts an Orchestrator job, and the robot that takes it decides the | ||
| project type: serverless cloud robots run only background, cross-platform | ||
| projects (vendor documentation), and jobs a Flow starts have run on them even | ||
| where the folder also had an unattended Windows robot. So a process a Flow | ||
| starts targets the cross-platform framework unless the folder's robots are |


Split from #3460 so each skill's changes reach its own code owners. Found while building flows from genomes.
Changes
flow initnames (SKILL.md): letters, numbers,_and-only;<Solution>keeps its spaces.CLI-LOOP.md):Data.incidentsis filled for a faulted run;Data.variablesErrormeans outputs unknown, not empty;EXPRESSION_DIAGNOSTICwarnings on error-envelope reads are expected.flow debuglimits (operate.md): runs only the default root; an RPA step does not run under a headless debug (exit0x33); a process or connection node the tenant lacks fails provisioning (2106) whilecheckandvalidatepass.manual-trigger.md): a form trigger works only as the default root.form-trigger.md,operate.md,rpa-workflow.md): atypes.fileinput is an attachment reference, never the content; hand it to a step that reads files.rpa-workflow.md): serverless robots run only cross-platform background projects; a process edited in Studio Web beside the Flow is XAML with VB.agent-resources.md, pointer frominline-agent.md):compilewrites noresource.jsonfor it, so the deployed agent is never offered the tool; template and steps to write it.connector-params.md): fields show empty there, and a Studio Web save drops their values.elementis the failing step's canvas label; a step with a handler still applies its{ updates }when it fails..var()from a body step.