diff --git a/skills/uipath-automationhub/SKILL.md b/skills/uipath-automationhub/SKILL.md index b61ddf5a5c..ce34ac5b2f 100644 --- a/skills/uipath-automationhub/SKILL.md +++ b/skills/uipath-automationhub/SKILL.md @@ -68,5 +68,6 @@ Every addition keeps the skill's three invariants: collect inputs before the fir ## Notes - **Cloud token only** — authorization is the user's real AH permissions; you see and can do exactly what their AH role allows. +- **If Automation Hub isn't available on the tenant, say so plainly and stop** — never let it surface as a generic failure. Two cases with **different remedies**: *not enabled* (only an admin can fix it) and *reachable but never onboarded* (self-service). Signals, and the exact wording to quote verbatim rather than paraphrase, live in one home per transport: [`references/api-endpoints.md`](references/api-endpoints.md) → **Automation Hub not available on this tenant** for the raw-API flows, [`references/cli-commands.md`](references/cli-commands.md) → same heading for the CLI flows. - The publish flow fetches the idea-flow schema live, so it adapts automatically if fields change on the tenant. - **Open dependency:** in a hosted runtime (e.g. Process Scribe/Delegate) the cloud token is expected via the environment (Authentication, option 1). Confirm the runtime provides `UIPATH_CLI_AUTH_TOKEN` (or an equivalent) before relying on it in production. diff --git a/skills/uipath-automationhub/references/api-endpoints.md b/skills/uipath-automationhub/references/api-endpoints.md index c0d15ac95a..048da7d51c 100644 --- a/skills/uipath-automationhub/references/api-endpoints.md +++ b/skills/uipath-automationhub/references/api-endpoints.md @@ -138,5 +138,27 @@ Linked components for the process. | 400 | Validation — missing required field, invalid enum, empty `user_inputs`, missing `OVERVIEW_NAME` | | 401 | Unauthorized — token missing/expired, or `x-ah-openapi-auth` was wrongly sent | | 403 | Forbidden — the user lacks the AH permission (authorization = the user's real AH role) | -| 404 | Wrong URL, or AH not enabled on the tenant | +| 404 | Wrong URL, or AH not available on the tenant — see **Automation Hub not available on this tenant** below | | 409 | Duplicate process name | + +### Automation Hub not available on this tenant + +Two distinct cases, with **different remedies** — don't collapse them, the advice differs: + +**1. AH is not enabled for the tenant.** The tenant has no Automation Hub service at all. Signals: a **404** whose body says `not found in organization`, or a **3xx redirect** to `portal_/unregistered` (following it would surface an HTML portal page as a JSON parse error). The user cannot fix this themselves — report exactly: + +> Please contact your administrator to enable Automation Hub on this tenant. + +**2. AH is reachable but the tenant was never onboarded into it.** The service answers **422 Tenant Lookup Error** on every call. This one *is* self-service — report exactly: + +> Automation Hub is reachable for this tenant but has not finished setup. Open Automation Hub in the browser once to complete it, then retry. + +In both cases: **stop after reporting** — do not retry, do not fall back to an admin OpenAPI token, and do not attempt the write against another tenant unless the user asks. Quote the message verbatim; don't paraphrase it. + +**Making the signals observable from `curl`.** `curl` reports the status but not *where* a 3xx points, so the first call each flow makes against the tenant asks for both: + +```bash +curl -s -w "\n%{http_code} %{redirect_url}" … +``` + +The last line is then ` `: `%{redirect_url}` is empty on any non-3xx and carries the resolved `Location` on a 3xx — which is what makes the `portal_/unregistered` case above distinguishable from an ordinary redirect. **Never add `-L`.** Following the redirect throws away the one diagnosable signal and hands you an HTML portal page, which then fails as a JSON parse error — exactly the generic failure this section exists to prevent. diff --git a/skills/uipath-automationhub/references/cli-commands.md b/skills/uipath-automationhub/references/cli-commands.md index 20c8a88dd5..28b36bb151 100644 --- a/skills/uipath-automationhub/references/cli-commands.md +++ b/skills/uipath-automationhub/references/cli-commands.md @@ -12,6 +12,17 @@ The CLI wraps the same Open API endpoints as [`api-endpoints.md`](api-endpoints. If a command fails with an authentication error, tell the user to run `uip login` — never ask for or handle a raw token yourself. +## Automation Hub not available on this tenant + +The CLI already classifies this for you — read its `Instructions` field: + +- `Instructions` mentioning **"not provisioned on this tenant"** → AH is not enabled. Report: *"Please contact your administrator to enable Automation Hub on this tenant."* +- `Instructions` mentioning **"no tenant record of its own yet"** → reachable but not onboarded. Report: *"Automation Hub is reachable for this tenant but has not finished setup. Open Automation Hub in the browser once to complete it, then retry."* + +Either way **stop** — don't retry and don't try another tenant unless asked, and quote the message verbatim rather than paraphrasing it. + +> This section is the **canonical wording for the CLI path**; the CLI flows reference it instead of restating it, so each message exists in exactly one place per transport (raw-API twin: [`api-endpoints.md`](api-endpoints.md) → **Automation Hub not available on this tenant**, which also carries the raw signals behind each case). The two homes exist because the CLI files stay self-contained for the day the raw-API fallback retires — keep them in sync if the wording ever changes. + ## Output envelope (every command) Always pass `--output json`. Success: diff --git a/skills/uipath-automationhub/references/get-process-cli-guide.md b/skills/uipath-automationhub/references/get-process-cli-guide.md index 7d349f6041..c42341e74a 100644 --- a/skills/uipath-automationhub/references/get-process-cli-guide.md +++ b/skills/uipath-automationhub/references/get-process-cli-guide.md @@ -19,6 +19,8 @@ Fetches one process (by id or search) and its documents, and downloads document uip ah automations get $PROCESS_ID --output json ``` +If the command fails with `Instructions` about AH **not being provisioned** on the tenant, or about the tenant having **no AH record yet**, report the message for the matching case, verbatim, from [`cli-commands.md`](cli-commands.md) → **Automation Hub not available on this tenant**, and stop. + `Data` is the projected record (`Id`, `Name`, `Phase`, `PhaseStatus`, `Tags`, …). Add `--all-fields` only when you need the raw record (e.g. `process_slug` for the deep link). `Failure` with not-found → no such process; auth error → `uip login`. ## Step 3: Fetch the documents diff --git a/skills/uipath-automationhub/references/get-process.md b/skills/uipath-automationhub/references/get-process.md index 36248058cd..b41a1080f6 100644 --- a/skills/uipath-automationhub/references/get-process.md +++ b/skills/uipath-automationhub/references/get-process.md @@ -9,19 +9,22 @@ Fetches one process (by id or search) and its documents from Automation Hub, aut - If the caller gives a **process id**, use it directly. - Otherwise search by name: ```bash - curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \ + curl -s -w "\n%{http_code} %{redirect_url}" -H "Authorization: Bearer $ACCESS_TOKEN" \ "$BASE_URL/$ORG/$TENANT/automationhub_/api/v1/openapi/automations?search=$QUERY&limit=20" ``` - If one clear match → use its `process_id`. If several → show a short list (name + id + owner) and ask the user to pick. If none → tell the user and stop. + The last line is ` ` (empty target unless 3xx). Check it **before** the results: a **404 / 3xx to `portal_/unregistered` / 422 tenant lookup** means AH isn't available on this tenant at all — handle it as in Step 2, don't report it as "no match". Never add `-L`. + + On a 200: one clear match → use its `process_id`. If several → show a short list (name + id + owner) and ask the user to pick. If none → tell the user and stop. ## Step 2: Fetch the process ```bash -curl -s -w "\n%{http_code}" -H "Authorization: Bearer $ACCESS_TOKEN" \ +curl -s -w "\n%{http_code} %{redirect_url}" -H "Authorization: Bearer $ACCESS_TOKEN" \ "$BASE_URL/$ORG/$TENANT/automationhub_/api/v1/openapi/automations/$PROCESS_ID" ``` +The last line is ` ` (empty target unless 3xx) — the target is what separates a `portal_/unregistered` redirect from any other 3xx. Never add `-L`. - **200** → keep the record; project to the useful fields for display (name, status/phase, category, owner, description). The raw record is large — don't dump it all unless asked. -- **401** → re-authenticate. **403** → the user can't view this process. **404** → no such process. +- **401** → re-authenticate. **403** → the user can't view this process. **404** → no such process — *unless* the body says `not found in organization` (or the call 3xx-redirects to `portal_/unregistered`, or answers **422 tenant lookup**), which means AH itself is not available on this tenant: report the message for the matching case, verbatim, from [`api-endpoints.md`](api-endpoints.md) → **Automation Hub not available on this tenant**, and stop. ## Step 3: Fetch the documents diff --git a/skills/uipath-automationhub/references/publish-process-cli-guide.md b/skills/uipath-automationhub/references/publish-process-cli-guide.md index a49cc315c5..68c11b567d 100644 --- a/skills/uipath-automationhub/references/publish-process-cli-guide.md +++ b/skills/uipath-automationhub/references/publish-process-cli-guide.md @@ -12,7 +12,7 @@ uip ah idea-flows list --output json - `Result: Success` → keep `Data` (flow names + ids) and tell the user "Connected to Automation Hub." - Auth failure → tell the user to run `uip login` (or, in Delegate, to sign in). Never ask for a raw token. -- `Failure` mentioning the tenant/enablement → AH is not enabled on this tenant; stop. +- `Failure` mentioning the tenant/enablement → AH is not available on this tenant. Report the message for the matching case, verbatim, from [`cli-commands.md`](cli-commands.md) → **Automation Hub not available on this tenant** — then **stop**; nothing later in this flow can succeed. ## Step 2: Pick the idea flow diff --git a/skills/uipath-automationhub/references/publish-process.md b/skills/uipath-automationhub/references/publish-process.md index 579997867f..2669d7c8fb 100644 --- a/skills/uipath-automationhub/references/publish-process.md +++ b/skills/uipath-automationhub/references/publish-process.md @@ -9,15 +9,17 @@ Creates one process in Automation Hub from a schema-driven payload and attaches Verify the resolved token with a cheap call — this also fetches the idea flows you need next: ```bash -curl -s -w "\n%{http_code}" \ +curl -s -w "\n%{http_code} %{redirect_url}" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ "$BASE_URL/$ORG/$TENANT/automationhub_/api/v1/openapi/idea-flows" ``` +The last line is ` ` — the target is empty unless the response was a 3xx. Read both: a 3xx alone is ambiguous, a 3xx **to `portal_/unregistered`** is the tenant-not-enabled signal below. Never add `-L`. + - **200** → save the `data` array (reused in Step 2) and tell the user "Connected to Automation Hub." - **401** → token missing/expired: if it came from `~/.uipath/.auth`, ask the user to run `uip login` again; re-resolve and retry. **Never** add `x-ah-openapi-auth` to "fix" a 401 — that routes to the admin-token path and guarantees failure. - **403** → the user is authenticated but lacks AH access on this tenant. -- **404 / network** → wrong URL or AH not enabled; confirm the org/tenant. +- **404 / 3xx to `portal_/unregistered` / 422 tenant lookup** → AH is not available on this tenant. Confirm the org/tenant first; if they're right, report the message for the matching case, verbatim, from [`api-endpoints.md`](api-endpoints.md) → **Automation Hub not available on this tenant** — then **stop**. Do not proceed until you have a 200.