uipath-api-workflow

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

UiPath API Workflow Assistant

UiPath API Workflow 助手

<!--skill-flavor:surface-summary:start-->
Build, run, and publish UiPath API Workflows — JSON files conforming to the CNCF Serverless Workflow DSL 1.0.0 with UiPath activity-type extensions. Executed by
@uipath/api-workflow-executor
via
uip api-workflow run
. Packaged as
Type: "Api"
projects via
uip solution pack
.
<!--skill-flavor:surface-summary:end--> <!--skill-flavor:host-command-contract:start--> <!--skill-flavor:host-command-contract:end-->
<!--skill-flavor:surface-summary:start-->
构建、运行和发布UiPath API工作流——符合CNCF Serverless Workflow DSL 1.0.0标准并扩展了UiPath活动类型的JSON文件。通过
@uipath/api-workflow-executor
执行,命令为
uip api-workflow run
。通过
uip solution pack
打包为
Type: "Api"
类型的项目。
<!--skill-flavor:surface-summary:end--> <!--skill-flavor:host-command-contract:start--> <!--skill-flavor:host-command-contract:end-->

When to Use This Skill

何时使用此技能

  • User wants to create or edit an API workflow JSON file
<!--skill-flavor:surface-lifecycle-scope:start-->
  • User wants to run an API workflow locally with
    uip api-workflow run
  • User wants to package an API workflow project into
    .nupkg
    / solution
    .zip
  • User wants to publish an API workflow to UiPath Cloud / Orchestrator
<!--skill-flavor:surface-lifecycle-scope:end-->
  • User asks about activity types (Sequence, Assign, JavaScript, If, ForEach, DoWhile, Break, TryCatch, Wait, Response, HTTP Request, Connector)
  • User asks about nested control flow — If inside ForEach, TryCatch around a loop, conditional Break, multi-way branching, etc.
  • User asks for an Integration Service connector activity (Gmail Send Email, Outlook Get Newest Email, GitHub Search Issues, Slack Send Message, etc.) — follow the discovery flow in references/connector-activity-discovery.md
  • User asks for a generic HTTP Request that needs to render in StudioWeb's designer — same discovery flow
  • User asks about JavaScript expressions,
    $context
    ,
    $input
    ,
    $workflow
    ,
    WorkflowStart
    , or the
    export.as
    pattern
<!--skill-flavor:surface-operations-scope:start-->
  • User asks how to debug a failing API workflow run — the local
    validate
    run --no-auth
    loop, or a post-publish cloud run (job logs/traces). See references/operating-published-workflows.md
  • User wants to operate a published workflow — invoke it (HTTP/schedule/Integration Service event trigger), start/list/stop its Orchestrator jobs, or manage the Integration Service connections it uses (
    uip is connections list
    /
    ping
    /
    edit
    ). See references/operating-published-workflows.md
<!--skill-flavor:surface-operations-scope:end-->
Do NOT use for:
.flow
Maestro flows (→
uipath-maestro-flow
),
.xaml
/ coded RPA (→
uipath-rpa
), coded agents (→
uipath-agents
), Coded Web Apps (→
uipath-coded-apps
).
  • 用户想要创建或编辑API工作流JSON文件
<!--skill-flavor:surface-lifecycle-scope:start-->
  • 用户想要使用
    uip api-workflow run
    本地运行API工作流
  • 用户想要将API工作流项目打包
    .nupkg
    /解决方案
    .zip
    文件
  • 用户想要将API工作流发布到UiPath云/Orchestrator
<!--skill-flavor:surface-lifecycle-scope:end-->
  • 用户询问活动类型(Sequence、Assign、JavaScript、If、ForEach、DoWhile、Break、TryCatch、Wait、Response、HTTP Request、Connector)
  • 用户询问嵌套控制流——ForEach内嵌套If、TryCatch包裹循环、条件Break、多分支等
  • 用户需要集成服务连接器活动(Gmail发送邮件、Outlook获取最新邮件、GitHub搜索问题、Slack发送消息等)——遵循references/connector-activity-discovery.md中的发现流程
  • 用户需要可在StudioWeb设计器中渲染的通用HTTP Request——使用相同的发现流程
  • 用户询问JavaScript表达式、
    $context
    $input
    $workflow
    WorkflowStart
    export.as
    模式
<!--skill-flavor:surface-operations-scope:start-->
  • 用户询问如何调试运行失败的API工作流——本地
    validate
    run --no-auth
    循环,或发布后的云端运行(作业日志/跟踪信息)。详见references/operating-published-workflows.md
  • 用户想要操作已发布的工作流——调用它(HTTP/调度/集成服务事件触发器)、启动/列出/停止其Orchestrator作业,或管理它使用的集成服务连接(
    uip is connections list
    /
    ping
    /
    edit
    )。详见references/operating-published-workflows.md
<!--skill-flavor:surface-operations-scope:end-->
请勿用于:
.flow
Maestro工作流(请使用
uipath-maestro-flow
)、
.xaml
/编码式RPA(请使用
uipath-rpa
)、编码式代理(请使用
uipath-agents
)、编码式Web应用(请使用
uipath-coded-apps
)。

Core Principles

核心原则

  1. Know before you write. Read the existing workflow file before editing. Read an example template before creating from scratch.
<!--skill-flavor:runtime-validation-contract:start-->
  1. Start minimal, iterate to correct. Add one activity at a time. Run with
    --no-auth --output json
    after each addition. Fix what breaks. Repeat.
  2. Validate before running.
    uip api-workflow validate
    is the offline static pre-flight (autonomous);
    uip api-workflow run
    is the runtime validator that catches what static analysis can't (live HTTP, expression evaluation, connection state) and needs user consent. See rules 20–21.
<!--skill-flavor:runtime-validation-contract:end-->
  1. Fix errors by category. Triage: Structure > Expression > Activity Config > Logic. Higher-category fixes often resolve lower-category errors automatically.
  1. 先了解再编写。编辑前先读取现有工作流文件,从零创建前先查看示例模板。
<!--skill-flavor:runtime-validation-contract:start-->
  1. 从最简开始,逐步迭代完善。每次添加一个活动,添加后使用
    --no-auth --output json
    运行。修复出现的问题,重复此过程。
  2. 运行前先验证
    uip api-workflow validate
    是离线静态预检查(自主执行);
    uip api-workflow run
    是运行时验证,可捕获静态分析无法发现的问题(实时HTTP请求、表达式求值、连接状态),且需要用户同意。详见规则20-21。
<!--skill-flavor:runtime-validation-contract:end-->
  1. 按类别修复错误。优先级:结构错误 > 表达式错误 > 活动配置错误 > 逻辑错误。高优先级类别的修复通常会自动解决低优先级类别的错误。

Critical Rules

关键规则

Rule 0 — Escalate big design forks before you build (highest priority, read first). When the happy path doesn't work out of the box and the resolution is a judgment call the user would reasonably want to own, STOP and ask before committing to a branch. Present the concrete options with their trade-offs and a recommended default; proceed only on the user's answer. Triggers (non-exhaustive): no valid connection for a required activity (rule 16); no curated activity exists and the choice is generic activity vs. raw Http kind vs. a different connector; the requested operation isn't exposed by any resolvable activity and the fallback is a hand-built HTTP call against an undocumented endpoint; an input the prompt assumed is missing and the alternatives are placeholder, hardcoded value, or new workflow input; the prompt is satisfiable by structurally different workflows (single connector call vs. ForEach over a list). This does NOT cover mechanical choices with an obvious answer (variable names, activity key suffixes, export-pattern selection) — decide those and move on. Reserve escalation for forks where guessing wrong wastes work or ships something the user didn't intend.
Ask the fork BEFORE branch-specific research, not after. Once you spot a structural fork, do only the shared work needed to surface the options (the cheap
resolve
that proves no curated activity exists, the
connections list
/
ping
that proves no connection works), then ask. Do NOT pre-research every branch — stubbing each candidate activity, describing resources, drafting alternative workflow shapes — so the user can "pick from finished work." The user picks one branch; deep work on the others is thrown away. Sequence: detect fork → minimal shared discovery → ask → then research and build only the chosen branch.
  1. Workflow file is JSON, not YAML. Top-level keys:
    document
    (with
    dsl: "1.0.0"
    ),
    evaluate
    (
    language: "javascript"
    ,
    mode: "strict"
    ),
    do
    (one root sequence — named
    Sequence_1
    in the template skeleton, but the literal key may differ in existing workflows; always read the actual key from the file before editing — containing
    WorkflowStart
    + user activities). See references/workflow-file-format.md.
  2. WorkflowStart
    is always the first activity
    inside the root sequence's
    do
    array. It hydrates variable defaults into
    $context.variables
    and forwards inputs to
    $input
    . Never remove, rename, or modify it.
    isTransparent: true
    (only
    WorkflowStart
    uses
    true
    ).
  3. Every activity is a single-key object wrapped in the
    do
    array:
    { "<ActivityKey>": { ...activity body... } }
    . Activity keys must be globally unique across the whole workflow — including
    #Wrapper
    ,
    #Then
    ,
    #Else
    ,
    #Body
    suffixes.
  4. Every activity should
    export
    its output
    to propagate state. Two patterns:
    • Variables (Assign only):
      { ...$context, variables: { ...$context.variables, ...$output } }
    • Outputs (everything else):
      { ...$context, outputs: { ...$context?.outputs, "<ActivityKey>": $output } }
      See references/expressions-and-context.md.
<!--skill-flavor:designer-literal-runtime-comparison:start-->
  1. String literals in
    Assign.set
    /
    Response
    / If
    when
    MUST be wrapped as
    "${'literal'}"
    — a JS string inside an expression. Plain
    "literal"
    runs fine under
    uip api-workflow run
    , but StudioWeb's designer normalizes unwrapped values to
    "${literal}"
    on save
    (treating them as expressions you typed into the property panel). At runtime the bare identifier
    literal
    has no binding →
    ReferenceError: literal is not defined
    . Use single quotes inside the expression to avoid JSON escaping:
    "set": { "tier": "${'PLATINUM'}" }
    . Numbers, booleans, and references like
    ${$context.variables.X}
    need no extra wrapping. (Response payloads have a related but distinct constraint — see rule 15.) Scope: this rule applies to Assign / Response / If / variable contexts only. It does NOT apply to connector
    bodyParameters
    /
    queryParameters
    /
    pathParameters
    — those take BARE literals;
    ${'...'}
    there is read as an expression and the field is cleared on save.
    See rule 16 and references/connector-activity-discovery.md#field-shape-rules-flat-keys-bare-literals-renamed-export-hub-prefix. See references/troubleshooting.md.
<!--skill-flavor:designer-literal-runtime-comparison:end-->
  1. Each
    Assign
    activity MUST set exactly ONE variable.
    Assign.set
    is a single-key object, NOT a multi-variable update. StudioWeb's designer collapses multi-key
    set
    blocks to one key on save
    , silently dropping the others — the runtime then only updates the surviving key. To update N variables, use N separate Assign activities placed sequentially in the same
    do
    array. Example: instead of
    "set": { "sum": "${$context.variables.sum + 1}", "count": "${$context.variables.count + 1}" }
    (loses
    count
    after StudioWeb save), write two Assigns —
    Assign_Sum
    with
    "set": { "sum": "${...}" }
    and
    Assign_Count
    with
    "set": { "count": "${...}" }
    . Each runs in order; each Assign's variables export merges its single key into
    $context.variables
    .
  2. If activity requires the wrapper pattern.
    If_N#Wrapper
    contains
    If_N
    (switch),
    If_N#Then
    ,
    If_N#Else
    . Both
    #Then
    and
    #Else
    MUST end with
    "then": "exit"
    to prevent fall-through. Conditions in
    when
    MUST be wrapped in
    ${...}
    . For deeply-nested If patterns and multi-way branching, see references/control-flow-patterns.md.
  3. Loops (ForEach, DoWhile) require a
    #Body
    element
    inside
    do
    . ForEach body uses index-aware accumulation (resets on iteration 0); DoWhile body uses simple accumulation. Loop variables (
    each
    ,
    at
    ) are plain strings, NOT expressions.
  4. DoWhile
    for.in
    is always
    "${ [1] }"
    .
    The
    doWhile
    condition controls repetition. The body MUST update the condition variable, otherwise the loop runs forever.
  5. Nested loops MUST use distinct iterator/index names. Outer
    for.each: "outerItem"
    , inner
    for.each: "innerItem"
    . Reusing
    currentItem
    shadows the outer. "Distinct" just means "not the same string" — semantic (
    outerItem
    /
    innerItem
    ) and incremental (
    item1
    /
    item2
    ,
    currentItem
    /
    currentItem2
    ) naming both work.
  6. Loop iterators and catch error variables are prefixed with
    $
    in expressions.
    Declare
    for.each: "currentItem"
    (plain string, no
    $
    ); reference it everywhere else (in
    when
    conditions, in script bodies, in
    set
    expressions, in body export patterns) as
    $currentItem
    — the
    $
    is a literal character in the global identifier name.
    currentItem
    is not a reserved name —
    for.each: "customer"
    binds
    $customer
    ,
    for.each: "row"
    binds
    $row
    , etc. Same shape for
    for.at
    (
    $currentItemIndex
    ,
    $idx
    , etc.) and
    catch.as
    (
    $error
    ,
    $err
    , etc.). Empirically verified: the executor calls
    setVariables({"$currentItem": item, ...})
    currentItem
    (no
    $
    ) is not bound as a global. Forgetting the
    $
    produces
    <name> is not defined
    .
  7. Break exits only the innermost enclosing loop. To exit nested loops, set a flag variable + check it in the outer loop. Break value MUST be the string
    "true"
    , with
    then: "exit"
    and
    set: "${$input}"
    . Only valid inside a
    #Body
    .
  8. Use
    $workflow.input.<name>
    to read workflow inputs
    , never
    $input.<name>
    .
    $input
    is the task's input — for any non-first task, it's the previous task's output, NOT the workflow arguments.
  9. JavaScript scripts read
    $context
    /
    $workflow
    /
    $input
    as globals.
    Scripts MUST
    return
    a value. The task's
    run.script.arguments
    field is StudioWeb designer scaffolding — keep it as the standard
    "${{ \"$context\": $context, \"$workflow\": $workflow, \"$input\": $input }}"
    block for designer roundtrip; the runtime ignores it.
  10. Response activity shape — STRICT for StudioWeb roundtrip:
    • markJobAsFailed
      is a sibling of
      response
      , not nested inside it.
    • Always include
      "then": "end"
      — without it, the workflow does not terminate properly.
      then: "end"
      is for Response only;
      then: "exit"
      is for control-flow branches/loops.
    • Object-valued responses MUST use the single-expression form, NOT the JSON-object-with-
      ${}
      -fields form. StudioWeb's designer corrupts the latter on save.
      • ✗ Wrong (CLI runs but StudioWeb corrupts):
        "response": { "tier": "${$context.variables.tier}", "count": "${$context.variables.count}" }
      • ✓ Correct:
        "response": "${{ tier: $context.variables.tier, count: $context.variables.count }}"
        Inside the outer
        ${{ ... }}
        you are already in expression scope, so reference variables/outputs directly without an inner
        ${...}
        wrapper. JS object literal keys can be unquoted identifiers (
        tier:
        ,
        count:
        ); literal string values use single quotes (
        status: 'ok'
        ); numbers/booleans/references are bare. The designer leaves an already-wrapped single expression alone; the JSON-object form gets flattened to a stringified expression where inner
        ${...}
        substitutions are inside JS double-quoted strings (which don't interpolate), turning each field into the literal text of its expression.
      • Either
        "${ { ... } }"
        (single-brace, expression-of-object-literal) or
        "${{ ... }}"
        (double-brace, object-literal-expression form) is valid — both evaluate to the same JS object. Pick one and stay consistent within a workflow.
    • For single-value responses (returning one variable or one expression), the simple form is fine:
      "response": "${$context.outputs.Javascript_1}"
      or
      "response": "${'done'}"
      .
<!--skill-flavor:response-roundtrip-validation:start-->
- **On-disk is authoritative.** Even with the single-expression workaround, every StudioWeb designer save can re-trigger normalization passes that may corrupt the Response shape. After any designer roundtrip, re-validate with `uip api-workflow run --no-auth` and re-apply the workaround if needed. Until the designer fix ships, treat the file on disk as truth, not what the designer renders.
<!--skill-flavor:response-roundtrip-validation:end-->
  1. Connector activities (HTTP + Integration Service) come from
    uip api-workflow registry resolve
    +
    stub
    — never hand-author or guess.
    The stub computes
    metadata.configuration
    , the kind (
    UiPath.Http
    vs
    UiPath.IntSvc
    ), the endpoint (with hub prefix),
    SlotKey
    , and
    ExportBucketKey
    (which can differ — HTTP slot
    HttpRequest_1
    vs bucket
    http_request_1
    ). Use all of them verbatim; NEVER invent a
    uiPathActivityTypeId
    , hand-author
    metadata.configuration
    , or reconstruct a key from
    objectName
    . Non-negotiables (full step-by-step, field-shape rules, multipart, and worked examples in references/connector-activity-discovery.md):
    • A keyword
      resolve
      miss is NOT proof no curated activity exists — verify connector-first before giving up.
      resolve
      AND-matches every token, so a marketing phrase + guessed verb over-narrows (the product "UiPath Data Fabric" carries
      connectorKey: uipath-uipath-dataservice
      and activity names like "Create Entity Record" —
      resolve "data fabric insert"
      returns 0; fewer/truer tokens, not more). Before concluding none exists or falling back to a hand-built HTTP call (a Rule 0 fork): map the product/vendor → connector key with
      uip is connectors list --filter "<product>"
      , then enumerate with
      uip is activities list <connector-key>
      . Do NOT hardcode/guess the key — look it up. See the reference's Step 1 recovery.
    • IntSvc/vendor activities require a pinged connection.
      uip is connections ping <uuid>
      must succeed before authoring — listing-state ≠ runtime-state; an
      Enabled
      connection can still 401 in cloud. An empty listing is NOT proof no connection exists —
      uip is connections list
      is folder-scoped. On empty/failed listing, walk the fallbacks in order: unfiltered
      uip is connections list
      , then
      uip is connections list --all-folders
      (catches connections in other folders), re-pinging a different
      Id
      for that
      ConnectorKey
      each time.
    • No connection pings cleanly → STOP and ask the user — do not decide alone. Offer: (a) continue with a placeholder (stub without
      --connection-id
      , leaving the
      <REPLACE_WITH_VENDOR_CONNECTION_UUID>
      sentinel — workflow is structurally complete but 401s until replaced; only with explicit user consent), or (b) stop and wait for the user to create/fix the connection, then re-ping. Never silently emit the placeholder, never silently abort. (Instance of Rule 0 — escalate design forks.)
    • NEVER ship a
      <REPLACE_WITH_*>
      placeholder
      in
      with.connectionId
      /
      connectionResourceId
      / Http
      bodyParameters.url
      . StudioWeb renders it as a broken connection and the workflow 401s. The placeholder is a sentinel for "re-stub with the real value," not a fill-in-later field.
    • After every stub, cross-check required fields — the stub drops
      required: true
      request fields (e.g. Outlook
      getNewestEmail
      needs
      parentFolderId
      ). Confirm via
      uip is resources describe ... --operation <op>
      or the stub's own
      metadata.configuration
      inputFields; re-stub with
      --inputs
      if missing.
    • Connector params use flat dotted keys and BARE literals.
      "message.toRecipients": "..."
      , not nested objects; plain
      "x@y.com"
      , not
      "${'x@y.com'}"
      — rule 5's wrap is inverted here (
      ${'...'}
      clears the field on save). Real references (
      ${$context...}
      ) stay wrapped.
    • NEVER use Http kind with a vendor connection UUID (401 "Invalid Element token"). IntSvc output is wrapped: read
      $context.outputs.<ExportBucketKey>.content.<field>
      .
<!--skill-flavor:connector-solution-registration:start-->
- **(Solutions-mode + IntSvc only)** sync the connection into the catalogue: `uip api-workflow bindings sync --workflow <Workflow.json>` then `uip solution resource refresh --solution-folder <path>`. Skip for Http kind, non-connector activities, and standalone (no `Solution/`) projects.
<!--skill-flavor:connector-solution-registration:end--> <!--skill-flavor:runtime-invocation-io:start-->
  1. Pass input as a JSON string.
    --input-arguments '{"key":"value"}'
    . Invalid JSON exits 1.
  2. Always
    --output json
    when parsing CLI output programmatically. Success →
    { "Result": "Success", "Code": "WorkflowRun", "Data": {...} }
    . Failure →
    { "Result": "Failure", "Message": "...", "Instructions": "..." }
    with exit 1.
<!--skill-flavor:runtime-invocation-io:end--> <!--skill-flavor:project-creation:start-->
  1. Scaffold with
    uip api-workflow init
    ; publish goes through the solution packager.
    Create every API workflow project with
    uip api-workflow init <name>
    (rule 19a) — never hand-assemble the project files. Project-level CLI commands also exist:
    uip api-workflow build <projectDir>
    (compile) and
    uip api-workflow pack <projectDir> <outputDir>
    (single-project
    .nupkg
    , useful to test one project in isolation). Solution-level build/publish go through
    uip solution pack <solutionDir> <outputDir>
    +
    uip solution publish <package.zip>
    . There is NO
    uip api-workflow publish
    command. Project type must be
    "Api"
    in the solution
    .uipx
    .
19a. Create projects with
uip api-workflow init <name>
— it produces the correct Studio Web editable shape and wires the solution.
Run it from inside the solution directory (the folder containing the
.uipx
):
bash     uip api-workflow init <name> --output json   # add --skip-solution-registration for a standalone (no .uipx) project     
It scaffolds
project.uiproj
+
Workflow.json
+
entry-points.json
+
bindings_v2.json
and, when run inside a solution, auto-registers the project in the surrounding
.uipx
(correct
ProjectRelativePath
+ a fresh
Id
). Success →
Code: "ApiWorkflowInit"
. Then edit
Workflow.json
only.
**Which mode.** Default = `init` inside a solution (Studio Web-editable + deployable — what a shipped automation needs). Use `--skip-solution-registration` ONLY when the user explicitly wants a CLI-only/local workflow that never opens in Studio Web or ships in a solution; it still emits the full project folder (`<name>/Workflow.json` + siblings), just no `.uipx` wiring. Never emit a lone `Workflow.json` with no project files — even a throwaway local workflow gets a project.

**Why it matters:** a legacy `project.json` + `workflows/WF_*.json` layout (no `.uiproj`) passes every runtime gate — `validate`, `run`, `pack`, `publish`, deploy — but Studio Web rejects it as `invalid_project_folder` and never shows it. `init` is the one step that can't produce the wrong shape. Full layout + field rules: [references/workflow-file-format.md](references/workflow-file-format.md#project-structure-studio-web-editable-contract).

To **convert a legacy `project.json` project**, `init` a fresh sibling and move the existing workflow content into its `Workflow.json` (cleanest), or convert in place — see [references/troubleshooting.md](references/troubleshooting.md). Never wire it with `uip solution projects add/remove` (errors on an already-registered name; `remove`+`add` destroys the project `Id`).
<!--skill-flavor:project-creation:end-->
  1. uip api-workflow validate <Workflow.json>
    is the autonomous closure step for every authoring or edit cycle.
    Run it as the LAST command before asking the user anything about runtime. It's offline (no auth, no network, no side effects): JSON Schema + semantic checks on the static file. Output codes:
    • Result: "Success"
      ,
      Code: "ApiwfValidate"
      ,
      Data.Status: "Valid"
      (exit 0) — possibly with
      Data.Warnings
      . Proceed to rule 21 (ask the user whether to run).
    • Result: "Failure"
      (exit 1) — do NOT bother the user. Read
      Instructions
      , locate the offending activity by its JSON path (e.g.
      /do/0/Sequence_1/do/2/Mystery_1/metadata/activityType
      ), edit
      Workflow.json
      to fix it, then re-validate. Loop until pass.
    Reading the error list. AJV schema errors from
    oneOf
    branches produce duplicate "Missing required property" noise (each unmatched variant lists all its required fields). Focus on the semantic-tail errors — the ones with prose messages like
    Unknown activityType 'X'
    ,
    must contain a 'do' with inner 'switch'
    ,
    is missing 'metadata.configuration'
    ,
    Variable must have a non-empty 'type'
    . Those uniquely identify the root cause. Fix one root cause, re-validate, repeat — don't chase the schema-level fanout one by one.
<!--skill-flavor:runtime-validation-limit:start-->
**What validate catches:** malformed JSON; unknown `activityType` values (see VALID_ACTIVITY_TYPES list in the validate source); per-activity required keys (If → `do` + inner `switch`, Sequence → `do`, Assign → `set`, ForEach → `for` + `do`, DoWhile → `for` + `doWhile`, Connector → `call` + `metadata.configuration` + `essentialConfiguration`, Response → `response`, etc.); missing `metadata.activityType`/`displayName` (warnings); bad `evaluate.language`/`evaluate.mode`; duplicate or empty-named workflow variables; empty task lists. **What it does NOT catch:** wrong `selectedResourceId`, broken connector connection IDs, runtime expression errors (`ReferenceError: x is not defined`), unwrapped string literals (rule 5), multi-key `Assign.set` (rule 6) — those still need runtime validation via `uip api-workflow run` once the user consents.
<!--skill-flavor:runtime-validation-limit:end--> <!--skill-flavor:runtime-execution-consent:start-->
  1. Never run
    uip api-workflow run
    without an explicit user "yes."
    Validation (rule 20) is autonomous; running is not. Once validate passes, ask the user: (a) run now or skip, (b) if running, with
    --no-auth
    (fast, structure-only — IntSvc kind vendor calls fail) or with auth (real Integration Service calls — vendor side effects WILL happen: emails sent, tickets created, files uploaded). Suggest a default based on workflow content (
    --no-auth
    for control-flow-only + Http kind
    ImplicitConnection
    ; with-auth for any IntSvc kind vendor activity), but wait for the user's answer. Never invoke
    uip api-workflow run
    with auth on speculation — once a vendor call goes out, it can't be unsent.
<!--skill-flavor:runtime-execution-consent:end-->
规则0——在构建前先升级重大设计分支(最高优先级,请先阅读)。当常规路径无法直接生效,且解决方案需要用户自主判断时,请停止操作并询问用户。提供具体选项及其优缺点,并给出推荐默认方案;仅在用户回复后继续执行。触发场景(非 exhaustive):所需活动无有效连接(规则16);无现成活动,需选择通用活动/原始Http类型/其他连接器;请求的操作无法通过可解析活动实现, fallback方案是针对未公开端点手动构建HTTP调用;提示中假设存在的输入缺失,替代方案为占位符、硬编码值或新增工作流输入;提示可通过结构不同的工作流实现(单个连接器调用 vs 遍历列表的ForEach)。这不包括有明显答案的机械选择(变量名、活动键后缀、导出模式选择)——可自行决定并继续。仅在猜测错误会浪费工作或交付不符合用户预期的分支时,才需要升级询问。
在分支特定研究前先询问分支选择。一旦发现结构分支,仅执行必要的共享工作以呈现选项(例如通过
resolve
确认无现成活动,通过
connections list
/
ping
确认无可用连接),然后询问用户。请勿预先研究每个分支——例如为每个候选活动生成stub、描述资源、起草替代工作流结构——让用户“从完成的工作中选择”。用户只会选择一个分支,其他分支的深度工作将被丢弃。流程:检测分支 → 最小化共享发现 → 询问用户 → 仅研究并构建用户选择的分支。
  1. 工作流文件为JSON格式,而非YAML。顶级键:
    document
    (包含
    dsl: "1.0.0"
    )、
    evaluate
    language: "javascript"
    mode: "strict"
    )、
    do
    (一个根序列——模板骨架中名为
    Sequence_1
    ,但现有工作流中的实际键可能不同;编辑前务必从文件中读取实际键——包含
    WorkflowStart
    + 用户活动)。详见references/workflow-file-format.md
  2. WorkflowStart
    始终是根序列
    do
    数组中的第一个活动
    。它将变量默认值加载到
    $context.variables
    中,并将输入转发到
    $input
    。请勿删除、重命名或修改它。
    isTransparent: true
    (仅
    WorkflowStart
    使用
    true
    )。
  3. 每个活动都是包裹在
    do
    数组中的单键对象
    { "<ActivityKey>": { ...活动主体... } }
    。活动键必须在整个工作流中全局唯一——包括
    #Wrapper
    #Then
    #Else
    #Body
    后缀。
  4. 每个活动都应
    export
    其输出
    以传递状态。两种模式:
    • 变量(仅Assign)
      { ...$context, variables: { ...$context.variables, ...$output } }
    • 输出(其他所有活动)
      { ...$context, outputs: { ...$context?.outputs, "<ActivityKey>": $output } }
      详见references/expressions-and-context.md
<!--skill-flavor:designer-literal-runtime-comparison:start-->
  1. Assign.set
    /
    Response
    /If的
    when
    中的字符串字面量必须包裹为
    "${'literal'}"
    ——即表达式中的JS字符串。普通的
    "literal"
    uip api-workflow run
    下可正常运行,但StudioWeb设计器在保存时会将未包裹的值标准化为
    "${literal}"
    (将其视为在属性面板中输入的表达式)。运行时,裸标识符
    literal
    无绑定 →
    ReferenceError: literal is not defined
    。使用表达式内的单引号避免JSON转义:
    "set": { "tier": "${'PLATINUM'}" }
    。数字、布尔值和
    ${$context.variables.X}
    这类引用无需额外包裹。(响应负载有相关但不同的约束——详见规则15。)适用范围:此规则仅适用于Assign/Response/If/变量上下文。不适用于连接器的
    bodyParameters
    /
    queryParameters
    /
    pathParameters
    ——这些接受裸字面量
    ${'...'}
    会被视为表达式,保存时字段会被清空。详见规则16和references/connector-activity-discovery.md#field-shape-rules-flat-keys-bare-literals-renamed-export-hub-prefix。详见references/troubleshooting.md
<!--skill-flavor:designer-literal-runtime-comparison:end-->
  1. 每个
    Assign
    活动必须仅设置一个变量
    Assign.set
    是单键对象,而非多变量更新。StudioWeb设计器在保存时会将多键
    set
    块合并为一个键
    ,静默丢弃其他键——运行时仅更新保留的键。要更新N个变量,请使用N个独立的Assign活动,按顺序放置在同一个
    do
    数组中。示例:不要使用
    "set": { "sum": "${$context.variables.sum + 1}", "count": "${$context.variables.count + 1}" }
    (StudioWeb保存后会丢失
    count
    ),应编写两个Assign——
    Assign_Sum
    使用
    "set": { "sum": "${...}" }
    Assign_Count
    使用
    "set": { "count": "${...}" }
    。它们按顺序运行;每个Assign的变量导出会将其单键合并到
    $context.variables
    中。
  2. If活动需要使用包裹模式
    If_N#Wrapper
    包含
    If_N
    (开关)、
    If_N#Then
    If_N#Else
    #Then
    #Else
    必须以
    "then": "exit"
    结尾以防止穿透。
    when
    中的条件必须包裹在
    ${...}
    中。如需深度嵌套If模式和多分支,请查看references/control-flow-patterns.md
  3. 循环(ForEach、DoWhile)需要在
    do
    内包含
    #Body
    元素
    。ForEach主体使用索引感知累加(迭代0时重置);DoWhile主体使用简单累加。循环变量(
    each
    at
    )是普通字符串,而非表达式。
  4. DoWhile的
    for.in
    始终为
    "${ [1] }"
    doWhile
    条件控制重复次数。主体必须更新条件变量,否则循环会无限运行。
  5. 嵌套循环必须使用不同的迭代器/索引名称。外层
    for.each: "outerItem"
    ,内层
    for.each: "innerItem"
    。重复使用
    currentItem
    会覆盖外层变量。“不同”仅指“不是相同字符串”——语义命名(
    outerItem
    /
    innerItem
    )和增量命名(
    item1
    /
    item2
    currentItem
    /
    currentItem2
    )均有效。
  6. 循环迭代器和捕获错误变量在表达式中以
    $
    为前缀
    。声明时使用
    for.each: "currentItem"
    (普通字符串,无
    $
    );在其他所有地方(
    when
    条件、脚本主体、
    set
    表达式、主体导出模式)引用时使用
    $currentItem
    ——
    $
    是全局标识符名称中的字面字符。
    currentItem
    不是保留名称——
    for.each: "customer"
    绑定
    $customer
    for.each: "row"
    绑定
    $row
    ,依此类推。
    for.at
    $currentItemIndex
    $idx
    等)和
    catch.as
    $error
    $err
    等)的形式相同。经验证:执行器调用
    setVariables({"$currentItem": item, ...})
    ——
    currentItem
    (无
    $
    未被绑定为全局变量。忘记添加
    $
    会产生
    <name> is not defined
    错误。
  7. Break仅退出最内层的包围循环。要退出嵌套循环,请设置一个标志变量并在外层循环中检查它。Break值必须为字符串
    "true"
    ,同时设置
    then: "exit"
    set: "${$input}"
    。仅在
    #Body
    内有效。
  8. 使用
    $workflow.input.<name>
    读取工作流输入
    ,切勿使用
    $input.<name>
    $input
    任务的输入——对于非第一个任务,它是前一个任务的输出,而非工作流参数。
  9. JavaScript脚本将
    $context
    /
    $workflow
    /
    $input
    作为全局变量读取
    。脚本必须
    return
    一个值。任务的
    run.script.arguments
    字段是StudioWeb设计器的脚手架——保持标准的
    "${{ \"$context\": $context, \"$workflow\": $workflow, \"$input\": $input }}"
    块以支持设计器往返;运行时会忽略它。
  10. Response活动结构——StudioWeb往返严格要求
    • markJobAsFailed
      response
      的同级,而非嵌套在其中。
    • 始终包含
      "then": "end"
      ——没有它,工作流无法正确终止。
      then: "end"
      仅适用于Response;
      then: "exit"
      适用于控制流分支/循环。
    • 对象值响应必须使用单表达式形式,而非包含
      ${}
      字段的JSON对象形式。StudioWeb设计器在保存时会损坏后者。
      • ✗ 错误形式(CLI可运行但StudioWeb会损坏):
        "response": { "tier": "${$context.variables.tier}", "count": "${$context.variables.count}" }
      • ✓ 正确形式:
        "response": "${{ tier: $context.variables.tier, count: $context.variables.count }}"
        在外层
        ${{ ... }}
        内已处于表达式作用域,因此直接引用变量/输出,无需内层
        ${...}
        包裹。JS对象字面量键可以是未加引号的标识符(
        tier:
        count:
        );字面字符串值使用单引号(
        status: 'ok'
        );数字/布尔值/引用为裸值。设计器不会修改已包裹的单表达式;JSON对象形式会被扁平化为字符串化表达式,其中内层
        ${...}
        替换位于JS双引号字符串内(不会插值),导致每个字段变为其表达式的字面文本。
      • "${ { ... } }"
        (单大括号,对象字面量表达式)或
        "${{ ... }}"
        (双大括号,对象字面量表达式形式)均有效——两者求值结果相同。在一个工作流中选择一种形式并保持一致。
    • 对于单值响应(返回一个变量或一个表达式),简单形式即可:
      "response": "${$context.outputs.Javascript_1}"
      "response": "${'done'}"
<!--skill-flavor:response-roundtrip-validation:start-->
- **磁盘文件为权威版本**。即使使用单表达式解决方法,每次StudioWeb设计器保存仍可能触发标准化过程,导致Response结构损坏。任何设计器往返后,使用`uip api-workflow run --no-auth`重新验证,若需要则重新应用解决方法。在设计器修复发布前,以磁盘上的文件为准,而非设计器渲染的内容。
<!--skill-flavor:response-roundtrip-validation:end-->
  1. 连接器活动(HTTP + 集成服务)来自
    uip api-workflow registry resolve
    +
    stub
    ——切勿手动编写或猜测
    。stub会计算
    metadata.configuration
    、类型(
    UiPath.Http
    vs
    UiPath.IntSvc
    )、端点(带hub前缀)、
    SlotKey
    ExportBucketKey
    (可能不同——HTTP的slot为
    HttpRequest_1
    ,bucket为
    http_request_1
    )。请原样使用所有内容;切勿自行创建
    uiPathActivityTypeId
    、手动编写
    metadata.configuration
    或从
    objectName
    重构键。不可协商的规则(完整步骤、字段结构规则、多部分内容和示例详见references/connector-activity-discovery.md):
    • resolve
      未找到结果并不证明无现成活动——先验证连接器再放弃
      resolve
      会匹配每个标记,因此营销短语+猜测动词会过度缩小范围(产品“UiPath Data Fabric”的
      connectorKey: uipath-uipath-dataservice
      ,活动名称如“Create Entity Record”——
      resolve "data fabric insert"
      返回0;应使用更少/更准确的标记,而非更多)。在得出无现成活动或 fallback到手动构建HTTP调用(规则0分支)之前:使用
      uip is connectors list --filter "<product>"
      将产品/供应商映射到连接器键,然后使用
      uip is activities list <connector-key>
      枚举活动。切勿硬编码/猜测键——请查询。详见参考文档的步骤1恢复方法。
    • IntSvc/供应商活动需要已ping的连接。编写前必须确保
      uip is connections ping <uuid>
      成功——列表状态≠运行时状态;
      Enabled
      连接在云端仍可能出现401错误。列表为空并不证明无可用连接——
      uip is connections list
      是文件夹范围的。若列表为空/失败,请按以下顺序尝试:未过滤的
      uip is connections list
      ,然后
      uip is connections list --all-folders
      (捕获其他文件夹中的连接),每次重新ping该
      ConnectorKey
      的不同
      Id
    • 无连接可成功ping通→停止操作并询问用户——切勿自行决定。提供选项:(a) 使用占位符继续(不带
      --connection-id
      的stub,保留
      <REPLACE_WITH_VENDOR_CONNECTION_UUID>
      标记——工作流结构完整,但替换前会出现401错误;仅在用户明确同意时使用),或**(b)** 停止操作,等待用户创建/修复连接后重新ping。切勿静默输出占位符,也切勿静默中止。(规则0的实例——升级设计分支。)
    • 切勿在
      with.connectionId
      /
      connectionResourceId
      /Http的
      bodyParameters.url
      中保留
      <REPLACE_WITH_*>
      占位符
      。StudioWeb会将其渲染为损坏的连接,工作流会出现401错误。占位符是“使用真实值重新生成stub”的标记,而非后续填充的字段。
    • 每次生成stub后,交叉检查必填字段——stub会丢弃
      required: true
      的请求字段(例如Outlook的
      getNewestEmail
      需要
      parentFolderId
      )。通过
      uip is resources describe ... --operation <op>
      或stub自身的
      metadata.configuration
      inputFields确认;若缺失,使用
      --inputs
      重新生成stub。
    • 连接器参数使用扁平点分隔键和裸字面量
      "message.toRecipients": "..."
      ,而非嵌套对象;使用普通的
      "x@y.com"
      ,而非
      "${'x@y.com'}"
      ——规则5的包裹在此处相反
      ${'...'}
      会在保存时清空字段)。真实引用(
      ${$context...}
      )仍需包裹。
    • 切勿将Http类型与供应商连接UUID一起使用(会出现401“Invalid Element token”错误)。IntSvc输出是包裹的:读取
      $context.outputs.<ExportBucketKey>.content.<field>
<!--skill-flavor:connector-solution-registration:start-->
- **(仅解决方案模式 + IntSvc)** 将连接同步到目录:`uip api-workflow bindings sync --workflow <Workflow.json>`,然后`uip solution resource refresh --solution-folder <path>`。Http类型、非连接器活动和独立(无`Solution/`)项目可跳过此步骤。
<!--skill-flavor:connector-solution-registration:end--> <!--skill-flavor:runtime-invocation-io:start-->
  1. 以JSON字符串形式传递输入
    --input-arguments '{"key":"value"}'
    。无效JSON会以退出码1终止。
  2. 程序化解析CLI输出时始终使用
    --output json
    。成功→
    { "Result": "Success", "Code": "WorkflowRun", "Data": {...} }
    。失败→
    { "Result": "Failure", "Message": "...", "Instructions": "..." }
    ,退出码1。
<!--skill-flavor:runtime-invocation-io:end--> <!--skill-flavor:project-creation:start-->
  1. 使用
    uip api-workflow init
    生成脚手架;发布通过解决方案打包器完成
    。使用
    uip api-workflow init <name>
    创建所有API工作流项目(规则19a)——切勿手动组装项目文件。项目级CLI命令还包括:
    uip api-workflow build <projectDir>
    (编译)和
    uip api-workflow pack <projectDir> <outputDir>
    (单项目
    .nupkg
    ,用于隔离测试单个项目)。解决方案级构建/发布通过
    uip solution pack <solutionDir> <outputDir>
    +
    uip solution publish <package.zip>
    完成。没有
    uip api-workflow publish
    命令。解决方案
    .uipx
    中的项目类型必须为
    "Api"
19a. 使用
uip api-workflow init <name>
创建项目——它会生成正确的Studio Web可编辑结构并连接到解决方案
。从解决方案目录(包含
.uipx
的文件夹)中运行:
bash     uip api-workflow init <name> --output json   # 独立项目(无.uipx)添加--skip-solution-registration     
它会生成
project.uiproj
+
Workflow.json
+
entry-points.json
+
bindings_v2.json
,并且在解决方案目录中运行时,会自动将项目注册到周围的
.uipx
(正确的
ProjectRelativePath
+ 新的
Id
)。成功→
Code: "ApiWorkflowInit"
。之后仅编辑
Workflow.json
**选择哪种模式**。默认=在解决方案内`init`(Studio Web可编辑 + 可部署——已发布自动化所需的模式)。仅当用户明确需要仅CLI/本地工作流,且从不需在Studio Web中打开或在解决方案中发布时,才使用`--skip-solution-registration`;它仍会生成完整的项目文件夹(`<name>/Workflow.json` + 同级文件),只是没有`.uipx`连接。切勿仅生成单独的`Workflow.json`而无项目文件——即使是临时本地工作流也需要项目。

**为什么这很重要**:旧版`project.json` + `workflows/WF_*.json`布局(无`.uiproj`)可通过所有运行时检查——`validate`、`run`、`pack`、`publish`、部署——但Studio Web会将其拒绝为`invalid_project_folder`,且永远不会显示。`init`是唯一不会生成错误结构的步骤。完整布局+字段规则:[references/workflow-file-format.md](references/workflow-file-format.md#project-structure-studio-web-editable-contract)。

要**转换旧版`project.json`项目**,可生成一个新的同级项目,将现有工作流内容移动到其`Workflow.json`中(最简洁),或就地转换——详见[references/troubleshooting.md](references/troubleshooting.md)。切勿使用`uip solution projects add/remove`连接项目(已注册名称会报错;`remove`+`add`会破坏项目`Id`)。
<!--skill-flavor:project-creation:end-->
  1. uip api-workflow validate <Workflow.json>
    是每个创作或编辑周期的自主收尾步骤
    。在询问用户任何运行时相关问题之前,将其作为最后一个命令运行。它是离线的(无需授权、无网络、无副作用):对静态文件进行JSON Schema + 语义检查。输出代码:
    • Result: "Success"
      Code: "ApiwfValidate"
      Data.Status: "Valid"
      (退出码0)——可能包含
      Data.Warnings
      。继续执行规则21(询问用户是否运行)。
    • Result: "Failure"
      (退出码1)——切勿打扰用户。读取
      Instructions
      ,通过JSON路径定位有问题的活动(例如
      /do/0/Sequence_1/do/2/Mystery_1/metadata/activityType
      ),编辑
      Workflow.json
      修复问题,然后重新验证。循环直到通过。
    读取错误列表。来自
    oneOf
    分支的AJV schema错误会产生重复的“Missing required property”噪音(每个不匹配的变体都会列出其所有必填字段)。专注于语义尾部错误——带有散文式消息的错误,如
    Unknown activityType 'X'
    must contain a 'do' with inner 'switch'
    is missing 'metadata.configuration'
    Variable must have a non-empty 'type'
    。这些错误可唯一识别根本原因。修复一个根本原因,重新验证,重复此过程——不要逐个追踪schema级别的扩散错误。
<!--skill-flavor:runtime-validation-limit:start-->
**validate能捕获的问题**:格式错误的JSON;未知的`activityType`值(详见validate源码中的VALID_ACTIVITY_TYPES列表);每个活动的必填键(If→`do`+内部`switch`,Sequence→`do`,Assign→`set`,ForEach→`for`+`do`,DoWhile→`for`+`do`,Connector→`call`+`metadata.configuration`+`essentialConfiguration`,Response→`response`等);缺失的`metadata.activityType`/`displayName`(警告);错误的`evaluate.language`/`evaluate.mode`;重复或空名称的工作流变量;空任务列表。**validate无法捕获的问题**:错误的`selectedResourceId`、损坏的连接器连接ID、运行时表达式错误(`ReferenceError: x is not defined`)、未包裹的字符串字面量(规则5)、多键`Assign.set`(规则6)——这些仍需在用户同意后通过`uip api-workflow run`进行运行时验证。
<!--skill-flavor:runtime-validation-limit:end--> <!--skill-flavor:runtime-execution-consent:start-->
  1. 未经用户明确“同意”,切勿运行
    uip api-workflow run
    。验证(规则20)是自主的;运行则不是。验证通过后,询问用户:(a) 立即运行还是跳过,(b) 若运行,使用
    --no-auth
    (快速,仅验证结构——IntSvc类型的供应商调用会失败)还是带授权(真实的集成服务调用——会产生供应商端副作用:发送邮件、创建工单、上传文件)。根据工作流内容建议默认选项(仅控制流+Http类型
    ImplicitConnection
    使用
    --no-auth
    ;任何IntSvc类型的供应商活动使用带授权),但等待用户回复。切勿推测性地使用授权运行
    uip api-workflow run
    ——一旦发出供应商调用,就无法撤销。
<!--skill-flavor:runtime-execution-consent:end-->

Workflow Phases

工作流阶段

Phase 0: Discovery

阶段0:发现

Before touching anything, understand what exists.
For edit requests:
  1. Read the existing workflow file with
    Read
  2. Identify activity keys already in use (avoid collisions)
  3. Identify variables, inputs, outputs already declared
  4. Identify export patterns in use (stay consistent)
For create requests:
  1. Read assets/templates/api-workflow-template.json for the empty skeleton
  2. Read a closer example based on need:
    • Conditional branching with error handling → assets/templates/conditional-workflow-example.json
    • Loops with aggregation → assets/templates/loop-aggregation-example.json
    • Heavily nested control flow (TryCatch around DoWhile around If with Break) → assets/templates/nested-control-flow-example.json
  3. For nested patterns specifically, read references/control-flow-patterns.md — pattern catalog for If-in-If, ForEach-with-If, TryCatch-around-loop, conditional Break, etc.
在进行任何操作之前,先了解现有内容。
对于编辑请求:
  1. 使用
    Read
    读取现有工作流文件
  2. 识别已使用的活动键(避免冲突)
  3. 识别已声明的变量、输入、输出
  4. 识别正在使用的导出模式(保持一致)
对于创建请求:
  1. 读取assets/templates/api-workflow-template.json获取空骨架
  2. 根据需求读取更接近的示例:
    • 带错误处理的条件分支→assets/templates/conditional-workflow-example.json
    • 带聚合的循环→assets/templates/loop-aggregation-example.json
    • 深度嵌套控制流(TryCatch包裹DoWhile包裹带Break的If)→assets/templates/nested-control-flow-example.json
  3. 对于嵌套模式,请专门阅读references/control-flow-patterns.md——包含If嵌套If、ForEach内嵌套If、TryCatch包裹循环、条件Break等模式目录

Phase 1: Plan

阶段1:规划

Decide which activities to use and in what order.
User wantsActivity typeKey points
Set/transform variablesAssignSets
$context.variables
; uses variables export pattern
Run custom logicJavaScript (JsInvoke)Inline JS; access context via
$context
/
$workflow
/
$input
globals (NOT
arguments[0]
)
Branch on condition (2-way)If
#Wrapper
+
#Then
+
#Else
structure required
Branch on condition (3+ way)Chain of IfsEach
#Else
holds the next If — see control-flow-patterns.md
Iterate over collectionForEach
for.each
/
for.in
/
for.at
; needs
#Body
Repeat until conditionDoWhile
for.in: "${ [1] }"
; needs
#Body
; must update condition variable
Handle errors (whole batch)TryCatch around loopOne bad item kills the batch — see control-flow-patterns.md
Handle errors (skip & continue)TryCatch inside bodyOne bad item skipped, loop continues — see control-flow-patterns.md
Return result and endResponse
then: "end"
;
markJobAsFailed
sibling of
response
Pause executionWait
wait.seconds
/
minutes
/
milliseconds
Exit loop earlyBreak (in If)Wrap Break in an If — there's no "break when" condition on Break itself.
break: "true"
(string!),
then: "exit"
,
set: "${$input}"
Exit nested loopsFlag variable + Break twiceSet a flag in inner loop, check + Break in outer — see control-flow-patterns.md
Call an arbitrary REST API (catfacts, stock prices, weather, any public/internal endpoint)Unified HTTP Request (
call: "UiPath.Http"
, Http kind)
connectionId: "ImplicitConnection"
. NEVER
call: "http"
(block icon). Via rule 16's flow.
Call a vendor service via its UiPath connection (Gmail, Outlook, GitHub, Slack, …)Vendor curated activity (
call: "UiPath.IntSvc"
, IntSvc kind)
Needs a pinged connection UUID. Via rule 16's flow.
CRUD a connector object that has no curated activityGeneric activity (
ActivityType: "Generic"
in resolve output — "List Records", "Get Record", …; IntSvc kind)
Add
--object-name <object>
(from
uip is resources list
) to the stub. Prefer a curated activity when one exists. Via rule 16's flow.
Before generating, determine:
  1. Which activities are needed and in what order
  2. What unique keys to assign (check existing keys to avoid collision)
  3. What variables to declare (in
    document.metadata.variables.schema.document.properties
    )
  4. What inputs/outputs to declare (in
    input.schema
    /
    output.schema
    )
确定要使用的活动及其顺序。
用户需求活动类型关键点
设置/转换变量Assign设置
$context.variables
;使用变量导出模式
运行自定义逻辑JavaScript(JsInvoke)内联JS;通过
$context
/
$workflow
/
$input
全局变量访问上下文(NOT
arguments[0]
条件分支(2路)If需要
#Wrapper
+
#Then
+
#Else
结构
条件分支(3+路)If链每个
#Else
包含下一个If——详见control-flow-patterns.md
遍历集合ForEach
for.each
/
for.in
/
for.at
;需要
#Body
重复直到满足条件DoWhile
for.in: "${ [1] }"
;需要
#Body
;必须更新条件变量
处理错误(整批)TryCatch包裹循环一个错误项会终止整批——详见control-flow-patterns.md
处理错误(跳过并继续)TryCatch在主体内跳过一个错误项,循环继续——详见control-flow-patterns.md
返回结果并结束Response
then: "end"
markJobAsFailed
response
的同级
暂停执行Wait
wait.seconds
/
minutes
/
milliseconds
提前退出循环Break(在If内)将Break包裹在If中——Break本身没有“break when”条件。
break: "true"
(字符串!),
then: "exit"
set: "${$input}"
退出嵌套循环标志变量 + 两次Break在内层循环设置标志,在外层循环检查并Break——详见control-flow-patterns.md
调用任意REST API(猫事实、股票价格、天气、任何公共/内部端点)统一HTTP Request
call: "UiPath.Http"
,Http类型)
connectionId: "ImplicitConnection"
。切勿使用
call: "http"
(块图标)。遵循规则16的流程。
通过UiPath连接调用供应商服务(Gmail、Outlook、GitHub、Slack等)供应商现成活动
call: "UiPath.IntSvc"
,IntSvc类型)
需要已ping的连接UUID。遵循规则16的流程。
对无现成活动的连接器对象执行CRUD操作通用活动(resolve输出中的
ActivityType: "Generic"
——“List Records”、“Get Record”等;IntSvc类型)
在stub中添加
--object-name <object>
(来自
uip is resources list
)。优先使用现成活动。遵循规则16的流程。
生成前确定:
  1. 需要哪些活动及其顺序
  2. 分配哪些唯一键(检查现有键避免冲突)
  3. 声明哪些变量(在
    document.metadata.variables.schema.document.properties
    中)
  4. 声明哪些输入/输出(在
    input.schema
    /
    output.schema
    中)

Phase 2: Generate or Edit

阶段2:生成或编辑

For each activity, read its reference section in references/task-types.md, copy the minimal JSON, fill in values.
For CREATE: copy from a template, then add user activities AFTER
WorkflowStart
inside the root sequence (literally
Sequence_1.do
in the template skeleton).
For EDIT: read the file first, identify the exact insertion / replacement point, use
Edit
with sufficient context for unique matching.
Workflow skeleton:
json
{
  "document": { "dsl": "1.0.0", "name": "...", "version": "0.0.1", "namespace": "default", "metadata": { "variables": { "schema": { "format": "json", "document": { "type": "object", "properties": {...}, "title": "Variables" } } } } },
  "input":  { "schema": { "format": "json", "document": { "type": "object", "properties": {...}, "title": "Inputs" } } },
  "output": { "schema": { "format": "json", "document": { "type": "object", "properties": {...}, "title": "Outputs" } } },
  "do": [{ "Sequence_1": { "do": [ { "WorkflowStart": { /* system */ } }, /* user activities */ ], "metadata": {...} } }],
  "evaluate": { "mode": "strict", "language": "javascript" }
}
对于每个活动,阅读references/task-types.md中的参考部分,复制最小JSON,填充值。
创建时:从模板复制,然后在根序列(模板骨架中为
Sequence_1.do
)的
WorkflowStart
之后添加用户活动。
编辑时:先读取文件,确定确切的插入/替换点,使用带有足够上下文的
Edit
进行唯一匹配。
工作流骨架:
json
{
  "document": { "dsl": "1.0.0", "name": "...", "version": "0.0.1", "namespace": "default", "metadata": { "variables": { "schema": { "format": "json", "document": { "type": "object", "properties": {...}, "title": "Variables" } } } } },
  "input":  { "schema": { "format": "json", "document": { "type": "object", "properties": {...}, "title": "Inputs" } } },
  "output": { "schema": { "format": "json", "document": { "type": "object", "properties": {...}, "title": "Outputs" } } },
  "do": [{ "Sequence_1": { "do": [ { "WorkflowStart": { /* system */ } }, /* user activities */ ], "metadata": {...} } }],
  "evaluate": { "mode": "strict", "language": "javascript" }
}

Phase 3: Validate (static) then Run (with consent)

阶段3:验证(静态)然后运行(需同意)

<!--skill-flavor:validation-run-lifecycle:start-->
Validate autonomously (rule 20), fixing + re-validating until
Data.Status: "Valid"
:
bash
uip api-workflow validate ./my-workflow.json --output json
Once green, ask before running (rule 21) — pick the mode from workflow content:
ModeFlagWhat happensUse when
No-auth
--no-auth
Skips token loading. Structure / expressions / control flow validated. IntSvc vendor calls fail with a missing-token error.Control-flow-only, OR Http kind with
connectionId: "ImplicitConnection"
. Default for most iterations.
With auth(none)Uses the
uip login
token. Real Integration Service calls — vendor side effects happen.
An IntSvc vendor activity AND the user confirmed the real call is OK (email sent, ticket created, file uploaded).
State the consequence in the question (e.g. "running with auth WILL send a real email to
<recipient>
— (1) skip, (2)
--no-auth
, (3) run with auth?"), wait for the reply, then run
uip api-workflow run ./my-workflow.json [--no-auth] --output json
. If the user skips, give them the exact command and stop.
<!--skill-flavor:validation-run-lifecycle:end--> <!--skill-flavor:runtime-troubleshooting:start-->
Fix run failures in category order — Structure > Expression > Activity Config > Logic (higher categories often resolve lower ones). Full pitfall catalog: references/troubleshooting.md.
<!--skill-flavor:runtime-troubleshooting:end-->
<!--skill-flavor:validation-run-lifecycle:start-->
自主验证(规则20),修复并重新验证直到
Data.Status: "Valid"
bash
uip api-workflow validate ./my-workflow.json --output json
验证通过后,运行前询问用户(规则21)——根据工作流内容选择模式:
模式标志行为使用场景
无授权
--no-auth
跳过令牌加载。验证结构/表达式/控制流。IntSvc供应商调用会因令牌缺失失败。仅控制流,或使用
connectionId: "ImplicitConnection"
的Http类型。大多数迭代的默认选项。
带授权使用
uip login
令牌。执行真实的集成服务调用——会产生供应商端副作用。
包含IntSvc供应商活动,且用户确认真实调用可执行(发送邮件、创建工单、上传文件)。
在问题中说明后果(例如“带授权运行会向
<recipient>
发送真实邮件——(1) 跳过,(2)
--no-auth
,(3) 带授权运行?”),等待回复后运行
uip api-workflow run ./my-workflow.json [--no-auth] --output json
。若用户跳过,提供确切命令并停止。
<!--skill-flavor:validation-run-lifecycle:end--> <!--skill-flavor:runtime-troubleshooting:start-->
按类别顺序修复运行失败——结构错误 > 表达式错误 > 活动配置错误 > 逻辑错误(高优先级类别修复通常会解决低优先级类别错误)。完整问题目录:references/troubleshooting.md
<!--skill-flavor:runtime-troubleshooting:end-->

Phase 4: Package, Publish, and Operate

阶段4:打包、发布和操作

<!--skill-flavor:deployment-lifecycle:start-->
Once the workflow runs locally, deploy via the solution packager. If the project must open in Studio Web, confirm it uses the
init
-produced shape first (rule 19a) — runtime/pack success does not prove it.
Pack:
bash
uip solution pack <solutionDir> <outputDir> \
  --name <PACKAGE_NAME> \
  --version 1.0.0 \
  --output json
The packager auto-detects
Type: "Api"
projects, validates structure, copies workflow files, generates
operate.json
+
package-descriptor.json
, and produces a
.nupkg
wrapped in a
.zip
.
Publish:
bash
uip solution publish <outputDir>/<package>.zip \
  --tenant <TENANT_NAME> \
  --output json
Requires
uip login
.
Operate + diagnose the published workflow. Once deployed, the workflow is an Orchestrator API process — the local
uip api-workflow
verbs no longer apply to it. Invoke it (HTTP/schedule/Integration Service event trigger), start/list/stop its jobs, manage the Integration Service connections it uses, and read cloud-run logs/traces via
uip or
/
uip is
/
uip traces
. Full command map: references/operating-published-workflows.md. These are sibling-skill surfaces (
uipath-platform
,
uipath-troubleshoot
) — delegate there for depth.
<!--skill-flavor:deployment-lifecycle:end--> <!--skill-flavor:quick-start-create:start-->
<!--skill-flavor:deployment-lifecycle:start-->
工作流在本地运行成功后,通过解决方案打包器部署。若项目需在Studio Web中打开,请先确认它使用
init
生成的结构(规则19a)——运行/打包成功不代表它兼容Studio Web。
打包
bash
uip solution pack <solutionDir> <outputDir> \
  --name <PACKAGE_NAME> \
  --version 1.0.0 \
  --output json
打包器会自动检测
Type: "Api"
项目,验证结构,复制工作流文件,生成
operate.json
+
package-descriptor.json
,并生成包裹在
.zip
中的
.nupkg
文件。
发布
bash
uip solution publish <outputDir>/<package>.zip \
  --tenant <TENANT_NAME> \
  --output json
需要
uip login
操作并诊断已发布的工作流。部署后,工作流成为Orchestrator API流程——本地
uip api-workflow
命令不再适用于它。通过HTTP/调度/集成服务事件触发器调用它,启动/列出/停止其作业,管理它使用的集成服务连接,并通过
uip or
/
uip is
/
uip traces
读取云端运行日志/跟踪信息。完整命令映射:references/operating-published-workflows.md。这些是关联技能的范围(
uipath-platform
uipath-troubleshoot
)——如需深入内容请委托给这些技能。
<!--skill-flavor:deployment-lifecycle:end--> <!--skill-flavor:quick-start-create:start-->

Quick Start (CREATE from scratch)

快速入门(从零创建)

bash
undefined
bash
undefined

0. Create the solution (skip if one already exists). Creates ./MySolution/ with the .uipx.

0. 创建解决方案(已有则跳过)。创建包含.uipx的./MySolution/目录。

uip solution init MySolution --output json
uip solution init MySolution --output json

1. Scaffold the project — correct Studio Web shape + auto-registers in the .uipx (rule 19a).

1. 生成项目脚手架——正确的Studio Web结构并自动注册到.uipx中(规则19a)。

init's <name> arg takes no slashes, so cd into the solution dir first; it registers the

init的<name>参数不接受斜杠,因此先进入解决方案目录;它会将项目注册到最近的父级.uipx中。

project in the nearest parent .uipx. Creates MyApiProject/ with project.uiproj,

创建包含project.uiproj、Workflow.json、entry-points.json、bindings_v2.json的MyApiProject/目录。

Workflow.json, entry-points.json, bindings_v2.json.

cd ./MySolution uip api-workflow init MyApiProject --output json
cd ./MySolution uip api-workflow init MyApiProject --output json

2. Edit MyApiProject/Workflow.json to add user activities after WorkflowStart inside the root sequence

2. 编辑MyApiProject/Workflow.json,在根序列的WorkflowStart之后添加用户活动

3. Validate (offline, autonomous — fix + re-validate until Status: Valid)

3. 验证(离线自主执行——修复并重新验证直到Status: Valid)

uip api-workflow validate ./MyApiProject/Workflow.json --output json
uip api-workflow validate ./MyApiProject/Workflow.json --output json

4. Ask the user, then run (only on user "yes")

4. 询问用户,然后运行(仅在用户同意时)

uip api-workflow run ./MyApiProject/Workflow.json --no-auth --output json
uip api-workflow run ./MyApiProject/Workflow.json --no-auth --output json

5. Package (cwd is the solution dir)

5. 打包(当前目录为解决方案目录)

uip solution pack . ./build --name MyApiSolution --version 1.0.0 --output json
uip solution pack . ./build --name MyApiSolution --version 1.0.0 --output json

6. Publish

6. 发布

uip login uip solution publish ./build/MyApiSolution_1.0.0.zip --tenant MyTenant --output json # pack names the zip <name>_<version>.zip
<!--skill-flavor:quick-start-create:end-->
uip login uip solution publish ./build/MyApiSolution_1.0.0.zip --tenant MyTenant --output json # 打包器会将zip命名为<name>_<version>.zip
<!--skill-flavor:quick-start-create:end-->

Reference Navigation

参考导航

FileUse when
references/workflow-file-format.mdAuthoring or editing the JSON skeleton: top-level keys,
document.metadata.variables
schema,
input.schema
/
output.schema
,
WorkflowStart
references/http-retry-config.mdAdding workflow-level HTTP retry policy (
httpRetryConfig
) — scope (GET-only), constant/linear/exponential backoff formulas, defaults,
Retry-After
handling, anti-patterns
references/task-types.mdAdding/editing any single activity — exact JSON shape, required fields, export pattern, common mistakes, basic nesting hints per type
references/control-flow-patterns.mdCombining activities into hierarchical structures — nested If, ForEach inside DoWhile, TryCatch around/inside loops, conditional Break, multi-way branching, key uniqueness rules
references/connector-activity-discovery.mdAuthoring HTTP Request / Gmail / Outlook / GitHub / Slack / etc. activities via
uip api-workflow registry resolve
+
stub
— three-step flow, sample stub output, field-shape rules, multipart subsection, worked examples
references/expressions-and-context.mdWriting JS expressions, propagating outputs via
export.as
, accessing
$context
/
$input
/
$workflow
, JS_Invoke argument passing, strict-mode gotchas, key patterns
<!--skill-flavor:cli-reference-navigation:start-->
| references/cli-reference.md | All
uip
commands —
api-workflow init
,
run
,
build
,
pack
,
validate
,
solution init
,
solution pack
,
solution publish
,
login
|
<!--skill-flavor:cli-reference-navigation:end--> <!--skill-flavor:published-reference-navigation:start-->
| references/operating-published-workflows.md | Operating + diagnosing a published workflow — invoke via HTTP/schedule/event triggers, manage Integration Service connections (
uip is connections
), start/list/stop Orchestrator jobs (
uip or jobs
), read cloud-run logs/traces (
uip or jobs logs
,
uip traces spans get
). Delegates depth to
uipath-platform
/
uipath-troubleshoot
|
<!--skill-flavor:published-reference-navigation:end-->
| references/troubleshooting.md | Failed runs, structure/expression/loop/nesting/response/validation pitfalls, packaging errors, publish errors, debugging strategy |
<!--skill-flavor:reference-navigation-extra:start--> <!--skill-flavor:reference-navigation-extra:end-->
文件使用场景
references/workflow-file-format.md创作或编辑JSON骨架:顶级键、
document.metadata.variables
schema、
input.schema
/
output.schema
WorkflowStart
references/http-retry-config.md添加工作流级HTTP重试策略(
httpRetryConfig
)——范围(仅GET)、常量/线性/指数退避公式、默认值、
Retry-After
处理、反模式
references/task-types.md添加/编辑任何单个活动:确切JSON结构、必填字段、导出模式、常见错误、每种类型的基本嵌套提示
references/control-flow-patterns.md将活动组合为层级结构:嵌套If、DoWhile内的ForEach、TryCatch包裹/在循环内、条件Break、多分支、键唯一性规则
references/connector-activity-discovery.md通过
uip api-workflow registry resolve
+
stub
创作HTTP Request/Gmail/Outlook/GitHub/Slack等活动:三步流程、示例stub输出、字段结构规则、多部分内容小节、示例
references/expressions-and-context.md编写JS表达式、通过
export.as
传递输出、访问
$context
/
$input
/
$workflow
、JS_Invoke参数传递、严格模式陷阱、键模式
<!--skill-flavor:cli-reference-navigation:start-->
| references/cli-reference.md | 所有
uip
命令——
api-workflow init
run
build
pack
validate
solution init
solution pack
solution publish
login
|
<!--skill-flavor:cli-reference-navigation:end--> <!--skill-flavor:published-reference-navigation:start-->
| references/operating-published-workflows.md | 操作并诊断已发布的工作流——通过HTTP/调度/事件触发器调用、管理集成服务连接(
uip is connections
)、启动/列出/停止Orchestrator作业(
uip or jobs
)、读取云端运行日志/跟踪信息(
uip or jobs logs
uip traces spans get
)。深入内容委托给
uipath-platform
/
uipath-troubleshoot
|
<!--skill-flavor:published-reference-navigation:end-->
| references/troubleshooting.md | 运行失败、结构/表达式/循环/嵌套/响应/验证问题、打包错误、发布错误、调试策略 |
<!--skill-flavor:reference-navigation-extra:start--> <!--skill-flavor:reference-navigation-extra:end-->

Templates

模板

FileDescription
assets/templates/api-workflow-template.jsonEmpty valid workflow with
WorkflowStart
and empty schemas — drop activities into the root sequence (
Sequence_1.do
in this template) after
WorkflowStart
assets/templates/conditional-workflow-example.jsonIf branching with TryCatch — input validation + classification + error fallback
assets/templates/loop-aggregation-example.jsonDoWhile + ForEach + Assign accumulation — pure-compute aggregation pattern
assets/templates/nested-control-flow-example.jsonHeavy nesting demo — TryCatch around DoWhile around If with conditional Break
<!--skill-flavor:template-execution-proof:start-->
| assets/templates/connector-call-example.json | Http kind — HTTP Request curated activity (
call: "UiPath.Http"
) for arbitrary REST calls. Generated by
registry stub
against the catfacts URL. Shows the canonical shape:
connectionId: "ImplicitConnection"
,
unifiedTypesCompatible: true
,
savedJitInputFieldId: "in_http-request"
, URL in
bodyParameters.url
. Verified end-to-end with
uip api-workflow run --no-auth
. |
<!--skill-flavor:template-execution-proof:end-->
| assets/templates/vendor-curated-call-example.json | IntSvc kind — vendor curated activity (
call: "UiPath.IntSvc"
) using Outlook GetNewestEmail as exemplar. The
<REPLACE_WITH_VENDOR_CONNECTION_UUID>
placeholder is a sentinel — replace it with a pinged UUID from
uip is connections list/ping
before writing the workflow to disk. StudioWeb renders the literal placeholder as a broken connection if it survives. See rule 16. |
<!--skill-flavor:solution-resource-template:start-->
| assets/templates/solution-connection-resource-template.json | Solution connection resource — declares a IntSvc kind connection as a Solution resource. Write to
Solution/resources/solution_folder/connection/<connector-key>/<connection-name>.json
. Required for Solutions-mode projects; without it the StudioWeb properties panel flags the activity as having an invalid connection. |
<!--skill-flavor:solution-resource-template:end-->
文件描述
assets/templates/api-workflow-template.json空的有效工作流,包含
WorkflowStart
和空schema——将活动添加到根序列(此模板中为
Sequence_1.do
)的
WorkflowStart
之后
assets/templates/conditional-workflow-example.json带TryCatch的If分支——输入验证+分类+错误回退
assets/templates/loop-aggregation-example.jsonDoWhile+ForEach+Assign累加——纯计算聚合模式
assets/templates/nested-control-flow-example.json深度嵌套演示——TryCatch包裹DoWhile包裹带条件Break的If
<!--skill-flavor:template-execution-proof:start-->
| assets/templates/connector-call-example.json | Http类型——用于任意REST调用的HTTP Request现成活动(
call: "UiPath.Http"
)。通过
registry stub
针对catfacts URL生成。显示标准结构:
connectionId: "ImplicitConnection"
unifiedTypesCompatible: true
savedJitInputFieldId: "in_http-request"
、URL在
bodyParameters.url
中。已通过
uip api-workflow run --no-auth
端到端验证。 |
<!--skill-flavor:template-execution-proof:end-->
| assets/templates/vendor-curated-call-example.json | IntSvc类型——供应商现成活动(
call: "UiPath.IntSvc"
),以Outlook GetNewestEmail为例。
<REPLACE_WITH_VENDOR_CONNECTION_UUID>
是标记——写入工作流到磁盘前,将其替换为
uip is connections list/ping
返回的已ping UUID。StudioWeb会将字面占位符渲染为损坏的连接。详见规则16。 |
<!--skill-flavor:solution-resource-template:start-->
| assets/templates/solution-connection-resource-template.json | 解决方案连接资源——将IntSvc类型连接声明为解决方案资源。写入
Solution/resources/solution_folder/connection/<connector-key>/<connection-name>.json
。解决方案模式项目必需;否则StudioWeb属性面板会将活动标记为连接无效。 |
<!--skill-flavor:solution-resource-template:end-->

Anti-patterns

反模式

The mistakes an agent makes most often (each maps to a Critical Rule above — see it for the full reasoning):
  • Do NOT use
    call: "http"
    for a REST call — it's the training-data default, but StudioWeb rejects it (renders as a "block" icon). Use
    call: "UiPath.Http"
    from
    registry stub
    . See rule 16.
  • Do NOT wrap connector
    bodyParameters
    /
    queryParameters
    literals as
    ${'literal'}
    — rule 5's wrap is inverted for connectors; bare literals only, or the field clears on save. See rule 16.
  • Do NOT ship a
    <REPLACE_WITH_*>
    placeholder in a workflow — StudioWeb renders it as a broken connection and it 401s. No pinged UUID → ask the user. See rule 16.
  • Do NOT read workflow inputs as
    $input.<name>
    from a non-first activity — use
    $workflow.input.<name>
    . See rule 13.
<!--skill-flavor:runtime-execution-antipattern:start-->
  • Do NOT invoke
    uip api-workflow run
    autonomously, and never with auth without an explicit "yes" — vendor calls have irreversible side effects (emails sent, tickets created). See rules 20–21.
<!--skill-flavor:runtime-execution-antipattern:end--> <!--skill-flavor:project-creation-antipatterns:start-->
  • Do NOT hand-assemble a project (
    project.json
    +
    main.json
    /
    workflows/WF_*.json
    ). Scaffold with
    uip api-workflow init <name>
    — it writes the correct
    project.uiproj
    shape and registers it in the
    .uipx
    . The legacy
    project.json
    -only shape runs and packs but Studio Web rejects it (
    invalid_project_folder
    ) and never shows it. See rules 19–19a.
  • Do NOT emit a lone
    Workflow.json
    with no project files, even for a quick local run. It runs under
    uip api-workflow run
    but is not a Studio Web project — can't be edited or shipped. Every workflow lives in an
    init
    -scaffolded project (
    --skip-solution-registration
    when no solution is needed). See rule 19a ("Which mode").
  • Do NOT wire a project into the solution with
    uip solution projects add/remove
    — it errors on an already-registered name, and
    remove
    +
    add
    destroys the project
    Id
    .
    init
    registers it; for an already-built project, edit the
    .uipx
    ProjectRelativePath
    in place. See rule 19a.
  • Do NOT trust "it packed / published / ran" as proof a project opens in Studio Web — every runtime gate passes on the wrong shape. Scaffolding with
    init
    is what guarantees it (rule 19a).
<!--skill-flavor:project-creation-antipatterns:end-->
代理最常犯的错误(每个错误对应上述关键规则——查看规则获取完整原因):
  • 切勿使用
    call: "http"
    进行REST调用——这是训练数据中的默认值,但StudioWeb会拒绝它(渲染为“块”图标)。使用
    registry stub
    生成的
    call: "UiPath.Http"
    。详见规则16。
  • 切勿将连接器
    bodyParameters
    /
    queryParameters
    字面量包裹为
    ${'literal'}
    ——规则5的包裹在此处相反;仅使用裸字面量,否则保存时字段会被清空。详见规则16。
  • 切勿在工作流中保留
    <REPLACE_WITH_*>
    占位符——StudioWeb会将其渲染为损坏的连接,且会出现401错误。若无已ping的UUID→询问用户。详见规则16。
  • 切勿从非第一个活动中使用
    $input.<name>
    读取工作流输入——使用
    $workflow.input.<name>
    。详见规则13。
<!--skill-flavor:runtime-execution-antipattern:start-->
  • 切勿自主调用
    uip api-workflow run
    ,且未经明确同意切勿带授权运行——供应商调用具有不可逆的副作用(发送邮件、创建工单)。详见规则20-21。
<!--skill-flavor:runtime-execution-antipattern:end--> <!--skill-flavor:project-creation-antipatterns:start-->
  • 切勿手动组装项目(
    project.json
    +
    main.json
    /
    workflows/WF_*.json
    )。使用
    uip api-workflow init <name>
    生成脚手架——它会写入正确的
    project.uiproj
    结构并注册到
    .uipx
    中。旧版仅
    project.json
    的结构可运行和打包,但StudioWeb会拒绝它(
    invalid_project_folder
    )且永远不会显示。详见规则19-19a。
  • 切勿仅生成单独的
    Workflow.json
    而无项目文件,即使是快速本地运行。它可在
    uip api-workflow run
    下运行,但不是StudioWeb项目——无法编辑或发布。每个工作流都应位于
    init
    生成的项目中(无需解决方案时使用
    --skip-solution-registration
    )。详见规则19a(“选择哪种模式”)。
  • 切勿使用
    uip solution projects add/remove
    将项目连接到解决方案——已注册名称会报错,且
    remove
    +
    add
    会破坏项目
    Id
    init
    会自动注册项目;对于已构建的项目,就地编辑
    .uipx
    中的
    ProjectRelativePath
    。详见规则19a。
  • 切勿认为“它可打包/发布/运行”就证明项目可在StudioWeb中打开——错误结构可通过所有运行时检查。使用
    init
    生成脚手架才能保证兼容性(规则19a)。
<!--skill-flavor:project-creation-antipatterns:end-->

Infinite Loop Prevention

无限循环预防

If a CLI command fails with the same error 2+ times, do NOT retry it. Investigate the root cause:
<!--skill-flavor:authentication-remediation:start-->
  • Not authenticated
    /
    Organization ID not available
    → ask the user to
    uip login
    , do not retry
<!--skill-flavor:authentication-remediation:end-->
  • File not found
    → check the path with
    ls
  • Repeated structural errors after fixes → re-read the workflow and the relevant reference section; you may be misreading the file
Maximum 3 attempts for any single operation. After 3 failures, stop and report what was tried.
若CLI命令连续2+次失败并出现相同错误,切勿重试。调查根本原因:
<!--skill-flavor:authentication-remediation:start-->
  • Not authenticated
    /
    Organization ID not available
    →询问用户执行
    uip login
    ,切勿重试
<!--skill-flavor:authentication-remediation:end-->
  • File not found
    →使用
    ls
    检查路径
  • 修复后仍重复出现结构错误→重新读取工作流和相关参考部分;可能误解了文件内容
任何单个操作最多尝试3次。3次失败后,停止操作并报告已尝试的步骤。