← Files Cargo CLIARCHIVED FILE

skills/cargo/references/gotchas.md

9.92 KB · Oct 4, 2026 · 12:30 UTC

↓ Download file

# Common gotchas

Silent-failure footguns and frequently confused command pairs across the Cargo CLI. Skim before designing a new workflow or debugging unexpected empty results.

| Gotcha                             | Detail                                                                                                                                                                                                                                        |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `conjonction` spelling             | Filter JSON uses `conjonction` (not `conjunction`). This is intentional. A typo here fails silently — no records returned.                                                                                                                    |
| `run create` vs `batch create`     | `run create` only works with **tool** workflows. Using a play's `workflowUuid` returns `playNotCompatible`.                                                                                                                                   |
| Inputs in `config` are dropped, not rejected | On a top-level action (`action execute` / `execute-batch`) the inputs go in `--data` / `--records`, and `config` is omitted entirely. It used to fail loudly (`A top-level action does not use action.config…`); that guard is gone, so `config` is stripped and the action runs with **no inputs** — a provider-side missing-field error, or an empty result, that never mentions `config`. |
| `get-output-schema` still requires `config` | Alone among the action commands. Paste the `action` object from `action list` (which carries no `config`) into `execute` and it runs; into `get-output-schema` and it fails `400 — expected record, received undefined` at `action.config`. Add `"config": {}` for that one call. The CLI's own `--help` examples for it omit `config` and therefore all 400. |
| Guessing an action slug | `cargo-ai orchestration action list <keywords>` searches connector, native, tool, and agent actions in one free call and hands back the `action` object (with `connectorUuid`) plus the action's credit costs. `unknown command` = the CLI predates it; refresh. |
| `cargo-ai mcp` with no `--server` | Now bridges the first-party **platform MCP** (`mcp.getcargo.io/mcp`). It used to resolve "the workspace's only MCP server" and fail when there were none or several — so a bare `cargo-ai mcp` on an old CLI is a different server from a bare `cargo-ai mcp` on a new one. Pass `--server <uuid>` for a curated server either way. |
| `node execute` vs `action execute` | `action execute` is the default for running an operation (`--action` + `--data`, no workflow needed). `node execute` is **debug-only** — testing one node of a workflow you're authoring — and requires all five of `--workflow-uuid`, `--release-uuid`, `--node`, `--computed-config`, `--context`. Both bill credits. |
| Triggering a play                  | Use `batch create --data '{"kind":"filter","modelUuid":"<play.modelUuid>","filter":{"conjonction":"and","groups":[]}}'`. The `segmentUuid` from `play list` points at the play's internally generated segment and is rejected (`segmentLinkedToPlay`, or a misleading `noRecords` on older backends) however many rows the model holds. `{"kind":"segment"}` is for standalone segments from `segmentation segment list` only. |
| `--model-uuid` vs `--segment-uuid` | `segment fetch` and `segment download` require `--model-uuid`. Get it from `segment list` → `.modelUuid`.                                                                                                                                     |
| `run list` can't find "the last run" | `orchestration run list` **requires** `--workflow-uuid` — there is no unfiltered form, and a play's UUID is not a workflow UUID. To find a run from a symptom alone, query the `runs` table instead (no filter required): `orchestration query execute "SELECT uuid, workflow_uuid, record_title, status, created_at FROM runs ORDER BY created_at DESC LIMIT 10"`, or match `record_title ILIKE '%<domain>%'`. Full ladder: `../../cargo-diagnostics/references/run-trace.md` § 0. |
| `SELECT *` fails on `runs`          | Orchestration SQL caps a query at **50 columns read** and `runs` has 51, so `SELECT * FROM runs` returns `Limit for number of columns to read exceeded` — an error that reads like the table is unavailable when it isn't. Always name columns.  |
| Node slugs repeat within a release | `nodes[].slug` is **not** unique — one shipped waterfall has six nodes slugged `variables`, and a play has an `agent` and a `variables` node both slugged `classify`. Anything that walks the graph (diagrams, edge maps, "which node produced this") must key on `uuid`. Note the knock-on: `{{nodes.<slug>...}}` and `runContext.<slug>` are ambiguous for a repeated slug, so give nodes you reference downstream distinct slugs. |
| Run graph: `nodes` **or** `releaseUuid` | `run get` returns the inline `nodes` for an `action execute` run and a `releaseUuid` with **no** graph for a run from a deployed tool/play. Reading the graph means `run.nodes` first, `release get <releaseUuid>` otherwise. |
| Storage query table names          | `storage query execute` and `storage query download` reference tables as `<datasetSlug>.<modelSlug>` (e.g. `default.companies`).                                                                                                              |
| Token shown once                   | API token values are only returned at creation. Store immediately. `workspaceManagement token create` requires `--name` (no more `--from-user`).                                                                                              |
| Invoice amounts in cents           | `subscription get-invoices` returns `amount` in cents. Divide by 100.                                                                                                                                                                         |
| Plays vs tools                     | **Play** = reacts to data changes (segment-driven). **Tool** = triggered on demand (manual, API, cron).                                                                                                                                       |
| Batch data kinds                   | Play workflows accept: `segment`, `change`, `filter`, `recordIds`. Tool workflows accept: `file`, `records`.                                                                                                                                  |
| Third-party connector rate limits  | Only `kind: "connector"` nodes (Clearbit, HubSpot, etc.) have rate limits — native nodes do not. Errors grow silently as the batch runs. Start at 1 record, then 50, then 500 before full-scale. Add `retry` with backoff to connector nodes. |
| Template expressions fail silently | A `{{nodes.foo.bar}}` referencing a missing path resolves to `undefined` (no error) and the run still reports `success` — so branches take the wrong path and end-node values come out empty, silently. Verify the real shape with `run get <uuid>` → `runContext.<slug>` (node-level outputs **are** returned by the CLI). Agent output is nested under `.answer`. |
| Group results are an array         | A `group` node's output is an array of per-iteration `end` outputs: `{{nodes.<groupSlug>[0].<field>}}`. There is **no `.results` wrapper**, and `.map(x => …)` arrow callbacks aren't supported in expressions. |
| Context survives a `delay`         | Prior node outputs are **not** wiped by a `delay` — the run context is checkpointed (as JSON) and restored. The catch is JSON-serializability: store anything needed post-delay in a `variables` node, not a `python` node's `result`. |
| `context runtime execute` is ephemeral | `context runtime execute` runs commands in the sandbox but **does not push** any file changes. Use `runtime write` / `runtime edit` for persistent edits to the context repo.                                                             |
| `context runtime edit` must match exactly once | `--old-string` must occur exactly once in the file. Whitespace counts — read the file first and copy the substring verbatim. For multi-spot changes, do multiple targeted edits or use `write` to overwrite the whole file.       |
| Large exports don't belong in context      | Never read a full CSV/JSON export into the conversation — inspect with `head`/`jq` or a storage SQL query and pass files by path. A few preview rows in context, never the dataset.                                              |
| Never enroll a full batch first             | `batch create` / `action execute-batch` fan out across **every** record in the source — the mistake and the bill land together. Sample 10–20 records, report observed cost + hit-rate, then ask for approval quoting the **record count** and **credit estimate**. `kind: "segment"`/`"change"` have no limit — sample via `kind: "filter"` + `limit` or `recordIds`. See `../../cargo-orchestration/SKILL.md` → "Create a batch". |
| Count before you pay                        | Search actions bill on **returned** rows, not matched totals. Keep `limit` strict; a `limit: 1` probe sizes the whole pool for the price of one row. See `../../cargo-gtm/references/cost-discipline.md`.                        |
| Phone lookup is the ~10× lever              | Phone actions run 3–7 credits/record vs ~0.1–1 for email. Never in a default chain — explicit user request on qualified leads only.                                                                                              |
| Receipt before next step                    | After any paid action: report credits spent, balance remaining, and hit-rate before proposing what to do next. Estimates diverging from actuals get a one-line why (`billing usage get-metrics` is the source of truth).          |

SHA-256: 7ba90cb5a3f97a17a1f8b437782676f0670d9a100d2d48f0a64ac457898fcc8b