SKILL.md
SKILL.mdBrowse 2 files
9,155 tokens
40,625 bytes
Token encoding: o200k_base
Snapshot 8bff5da
1---2name: post-build-flow3description: >-4 Handles workflow verification and setup after build-workflow succeeds, or when5 the message contains workflow-verification-follow-up or workflow-setup-required.6 Load after direct builds, when verificationReadiness requires action, or on7 orchestrator verify/setup follow-up turns.8recommended_tools:9 - ask-user10 - verify-built-workflow11 - workflows12 - build-workflow13 - executions14---15 16# Post-Build Flow17 18Use this skill after `build-workflow` succeeds on a direct orchestrator build,19especially when the build result contains `postBuildFlow.required: true`, or when20the current message contains `<workflow-verification-follow-up>` or21`<workflow-setup-required>`.22 23One-off builds (`postBuildFlow.reason: "direct-one-off-build-succeeded"`) hand24off to the `one-off-operations` skill instead — verification is optional there25and completion is a live run with read-back. If both sets of instructions are26in context for a one-off build, the one-off flow wins.27 28These instructions are in English, but user-visible text you write while29following them stays in the user's conversation language.30 31For trigger `inputData` shapes, read32`${N8N_WORKSPACE_DIR}/knowledge-base/reference/trigger-input-data-shapes.md` in33the sandbox workspace when available, or load this skill's34`references/trigger-input-data-shapes.md` linked file.35 36## Setup panel37 38Use this section when the system prompt describes the persistent setup panel,39setup returns `announced: true`, or the current user input contains40`<workflow-test-request>`. Otherwise, keep the setup card flow below.41 42- Verify what the build can simulate before asking the user to finish setup.43 Missing credentials do not prevent this verification. Report which outputs44 were simulated. A simulated result does not prove a live connection.45- When setup returns `announced: true`, summarize the open items and any46 validation warnings. End the turn. The user can complete setup in the panel47 while chat stays available. Do not wait, poll, or open a trigger-test card.48- On a later user turn, trust `<workflow-setup-state>` over earlier setup49 results. If items settled, none remain open, and there are no validation50 warnings, verify the current saved configuration with `verify-built-workflow`.51 It refreshes the credential plan.52 Report remaining simulations or connection failures. Do not claim live53 success from the earlier build result.54- `<workflow-test-request>` in the current user input means the user clicked55 Execute. A block in conversation history does not request another execution.56 Use the workflow ID in the current block. Inspect its current57 `<workflow-setup-state>` and read the saved workflow with58 `workflows(action="get-as-code")`. Do not call `workflows(action="setup")`59 for this precheck. It announces setup and ends the turn. If the target is60 absent from the state block, inspect its saved configuration. If required61 setup cannot be confirmed, report what is missing and end the turn.62 If required items remain open for this63 workflow, report them and end the turn without a live run. Otherwise,64 use `executions(action="run")` with suitable trigger input. The user has65 already requested this test; do not ask whether they want it. The execution66 tool still enforces its approval policy. Do not publish the workflow to test it.67- Read the execution output and summarize what ran and what it returned. For68 failures, inspect `executions(action="debug")`. Fix the same workflow when69 possible. Use the current saved source so panel edits are preserved. Report70 unresolved setup or failures in chat. Before another live run, inspect the71 successful effect nodes from the failed run. Follow72 [Cleaning up after a live test](#cleaning-up-after-a-live-test) for any artifacts73 they left behind. After a repair and that artifact check, test the updated74 workflow and inspect its output. Do not substitute mocked verification75 for the requested execution.76 77A setup card that was already open keeps its apply and trigger-test resume78flow. Its result is not a panel announcement unless it has `announced: true`.79 80## Verification follow-up81 82When the current message contains `<workflow-verification-follow-up>`, verify83immediately from the payload's `obligation` — do not acknowledge first. If the84obligation is `ready_to_verify` or `verifying`, call `verify-built-workflow`. Do85**not** call `workflows(action="setup")` in this turn and do **not** declare the86workflow finished if `outcome.setupRequirement.status === "required"` — setup is87routed automatically as a separate `<workflow-setup-required>` step after88verification. For a multi-trigger outcome, verify every trigger that does not89yet have a recorded successful verification. Make all of these calls in this turn.90 91## Setup follow-up92 93When the current message contains `<workflow-setup-required>`, your first action94is to call `workflows(action="setup")` with the `workflowId` from the payload. Do95not verify, do not ask, do not write a message first — the inline setup card in96the n8n Assistant panel is the user-visible surface. If the result has97`announced: true`, use the persistent panel instructions above and end the turn.98If it returns `deferred:99true`, respect the user's choice and do not retry with any other setup tool.100A result carrying `skippedByUser` names credentials the user already passed on:101never re-open setup for those, in this turn or any later one — see102[Credentials the user skipped](#credentials-the-user-skipped).103After setup completes or is applied, follow104[Mocked verification live-test follow-up](#mocked-verification-live-test-follow-up)105if the payload or prior verification evidence says mocked credentials,106simulated node output, fixture overrides, temporary pin data, or another mocked107input was used.108 109### Choosing the credential type for a service110 111Pick in this order:112 1131. **A dedicated credential type** (`slackApi`, `notionApi`, …) whenever one114 exists — search with `credentials(action="search-types")`.1152. **Simplified Custom Auth** (`httpTemplatedCustomAuth`) for any service116 without a dedicated type whose auth is expressible as header/query/body117 values — which covers API keys and bearer tokens (`Authorization: Bearer118<token>` becomes `{"headers":{"Authorization":"Bearer {{api_key}}"}}`, not119 `httpBearerAuth`). Always provide a recipe (below) so the user only pastes120 their secret.1213. **Plain generic types** (`httpBasicAuth`, `httpDigestAuth`, `oAuth2Api`, …)122 only for what a template cannot express: basic auth's base64-encoded pair,123 digest's challenge-response, OAuth flows — or when the user explicitly asks124 for a specific plain type: an explicit user choice wins (setup accepts it125 with `allowPlainGenericAuth: true`).126 127### Credential recipes for Simplified Custom Auth128 129When the workflow authenticates a service through Simplified Custom Auth,130include `credentialHints` in the same `workflows(action="setup")` call so the131setup card pre-fills the credential and the user only pastes their secret —132instead of facing an empty JSON template they'd have to decode from the133provider's docs. Before composing the hints, load the134`credential-recipe-research` skill and execute its lookup procedure — the135template, `docsUrl` and `testUrl` must come from the provider documentation136it has you fetch, never from memory:137 138- `template` — the auth request parts (headers/qs/body) exactly as documented,139 with `{{placeholder}}` markers where the user's values go.140- `placeholders` — one entry per marker: `name`, user-facing `title`, an141 optional `info` clarifying the value itself — its format or which of the142 provider's tokens it is (e.g. "Starts with tvly-"). Never where to obtain143 it, and never a URL or domain: the user asks the n8n Assistant for that from144 the credential form. `type` is `password` unless clearly non-secret (at145 least one placeholder must stay `password`). Add `optional: true` only when146 the provider documents the value as optional (e.g. an org/region147 qualifier) — template entries referencing an empty optional placeholder are148 omitted from the request.149- `docsUrl` — the provider page where a logged-in user CREATES/COPIES the150 secret (e.g. `https://replicate.com/account/api-tokens`) — never the API151 reference. Not shown in the form: the n8n Assistant help thread uses it to152 send the user to the exact page. Found via the `credential-recipe-research`153 procedure; omit when it finds nothing conclusive.154- `testUrl` — a documented side-effect-free GET that rejects a bad key with155 401/403, used to verify the credential on save and later retests; never one156 of the workflow's own endpoints, never anything billable. Found via the157 `credential-recipe-research` procedure; omit when nothing qualifies — a158 credential without a testUrl saves fine and honestly shows "could not be159 verified", which beats a false green.160- `acceptedStatusCodes` — almost always omit; the user can adjust it later on161 the credential if a service's auth answers 401/403 to valid GETs.162- `suggestedName` — display name for the created credential.163 164Example — fal.ai's docs say requests use `Authorization: Key <FAL_KEY>` and165`GET https://api.fal.ai/v1/models/usage` is a documented side-effect-free166endpoint that rejects a bad key (the model-serving host `fal.run` is not a167key-check endpoint):168 169```json170{171 "action": "setup",172 "workflowId": "...",173 "credentialHints": [174 {175 "suggestedName": "fal.ai API Key",176 "template": {177 "headers": { "Authorization": "Key {{api_key}}" }178 },179 "placeholders": [180 {181 "name": "api_key",182 "title": "fal.ai API key",183 "info": "Key ID and secret, separated by a colon",184 "type": "password"185 }186 ],187 "docsUrl": "https://fal.ai/dashboard/keys",188 "testUrl": "https://api.fal.ai/v1/models/usage"189 }190 ]191}192```193 194Never put a real secret in a recipe — the user pastes it in the setup card and195it is stored redacted in the credential. Add `nodeName` when several nodes use196Simplified Custom Auth for different services. You cannot see the secret, but197once setup reports the credential applied, treat it as fully configured — the198`{{placeholder}}` markers live only in the template; the stored values replace199them at request time. If a live test later fails with an auth error, that is200the moment to have the user re-open the credential and re-paste the value.201 202If the user defers setup instead, don't hand them manual field-by-field203credential instructions for the n8n editor — tell them to reopen setup when204they're ready: the card pre-fills everything except their key.205 206### Credentials the user skipped207 208Skipping is remembered for the whole conversation. A setup result may carry209`skippedByUser` (nodes and credential types the user passed on), and a build210outcome may carry `setupRequirement.status === "not_required"` with211`reason: "skipped-by-user"`. In both cases the blocking setup card is off the212table for those credentials — including after later edits, rebuilds, and213`<workflow-setup-required>` steps. Asking again is the single most common214complaint about this flow.215 216Instead, in your normal message:217 218- name what stays unconfigured and what happens at runtime (e.g. "the Slack post219 will fail until a channel is selected; the email still sends"),220- offer to set it up whenever they want.221 222Only once the user asks for a specific credential — "connect Slack now", "let's223do the Slack setup", or picking it out of an offer you made — call224`workflows(action="setup", reopenSkipped: ["slackApi"])`, naming just what they225asked for so the rest stays skipped. A generic "yes" to an unrelated question is226not an ask.227 228Pass the `reopenWith` value the tool reported for that card, not the user's229wording — a credential type for a credential card, a node name for one that was230only missing a parameter. If nothing matches, setup answers with231`unknown_reopen_target` and the list you can choose from; pick from it or tell232the user what they named isn't part of this workflow. Don't fall back to233re-offering, the user already asked.234 235## Publishing and testing236 237**Publishing is never required for testing.** Both `executions(action="run")` and238`verify-built-workflow` inject `inputData` as the trigger's output — the239workflow does not need to be active. Form, webhook, chat, and other event-based240triggers are all testable while the workflow is unpublished. Never publish a241workflow as a precondition for running it.242 243**Webhook input must carry the fields the workflow reads.** A flat `inputData`244becomes the request `body` only; `query`, `headers` and `params` stay empty. When245any expression reads `$json.query.*`, `$json.headers.*` or `$json.params.*`, pass246the request envelope `{ body: {...}, query: {...}, headers: {...}, params: {...} }` (or a247`fixtureOverrides` entry on the trigger node). Otherwise the field resolves empty,248the run still succeeds, and that field is unverified — say so instead of249reporting it as working.250 251Do not proactively offer, recommend, or mention publishing until a successful252execution has run every required node on the claimed path without mocked253credentials, simulated node output, fixture overrides, or temporary pin data254for those nodes. A successful verification that used any of these is not255publish-readiness evidence. If the user explicitly asks to publish before a256live execution succeeds, warn that the live path remains untested, then follow257the requested publish flow.258 259`workflows(action="publish")` enforces this. While the latest verification left260nodes unreached or simulated, the call is refused and returns261`verificationDisclosure` — the coverage facts, generated from the run. Relay262those facts to the user and offer a live end-to-end test. Publish only if they263still ask, by calling publish again with `acknowledgeUnverified: true`. Never264set that flag to skip the disclosure. The user also sees the same facts in the265publish approval prompt, so a summary that contradicts them is visible to them.266 267Execution evidence can come from a run you started or a run the user started.268If the user says they ran the workflow manually, call269`executions(action="list", workflowId)`, identify the relevant run, and inspect270it with `executions(action="get", executionId)`. The user's statement alone is271not execution evidence. A user-run execution satisfies the publishing gate only272when the inspected result confirms success and that every required node on the273claimed path ran. Do not count it if mocked, simulated, fixture, or pinned output274was used. You may offer publishing after that confirmation.275 276For post-build verification of workflows produced by `build-workflow`, **always verify with277`verify-built-workflow`, never with raw `executions(action="run")`.** It reuses278the build outcome simulation plan, mocked credentials, and temporary pin data, so279destructive nodes are pinned and it is safe to call repeatedly. A raw280`executions(action="run")` runs the workflow live with no pin data, and on a281workflow you just verified it surfaces a redundant run-approval prompt to the282user right after verification already executed the workflow. For follow-up283requests like "verify again", call `verify-built-workflow` with `workflowId` even284if the original `workItemId` is not in context. For alternate deterministic285scenarios, pass `fixtureOverrides` keyed by simulated node name instead of trying286to force data through the trigger.287 288**Reserve `executions(action="run")` for runs the user explicitly asked for**289(e.g. "run it now", "execute it against my real data"). Never call it on your own290to re-test, expand coverage, or "prove the full chain" of a workflow you just291built or verified: re-run `verify-built-workflow` instead — with292`triggerNodeName` to reach another trigger's branch, or `fixtureOverrides` to293reach another branch within one trigger's run — or report the partial coverage294and let the user decide whether to run it.295If `fixtureOverrides` is rejected with `invalid_fixture_override`, the target296node was not classified as simulated in the build outcome. Do not retry the same297override. If that node's data controls a branch that needs verification and you298have the source file, load `workflow-builder`, declare representative `output`299fixtures on the controlling upstream node, rebuild the same workflow, and verify300again.301 302**Never edit or copy a saved workflow to reach a branch.** Disabling, deleting,303or reordering nodes to steer a test mutates the user's workflow and leaves it304broken for as long as the test runs — if it is published, its triggers fire305against the broken version. Building a throwaway second workflow is no better:306the evidence is gathered against a copy that can drift from the workflow the307user keeps, and the copy is left behind whenever the cleanup delete fails.308 309For a workflow with more than one trigger (`triggerNodes` has multiple entries),310**verify once per trigger**:311 312- Pass `triggerNodeName` to `verify-built-workflow` and call it once for each313 entry in `triggerNodes`. Naming no trigger verifies only the auto-detected314 one. An unresolvable name is rejected outright, so a rejected call means the315 name is wrong — re-read `triggerNodes`, never fall back to editing.316- Each pass reports `nodesNotReached` only for its selected trigger's main-flow317 branch. Coverage is the **union** across successful passes. Run every trigger318 before you report a workflow coverage gap. Different triggers can select319 different outputs of a shared Switch or If node.320- A failed rerun removes that trigger's earlier coverage. Verify that trigger321 again before you claim that the workflow is verified.322- Report each trigger and whether its branch ran. Use the combined `claim` to323 describe the result (see "Claiming success").324- When the user asked for a live run, pass `triggerNodeName` to325 `executions(action="run")` the same way — one run per trigger — and report326 each branch's result.327 328### Fixing a workflow that is already published329 330The publishing rules above assume a new workflow. A repair of a workflow that331is already published is different. That workflow runs in production right now,332and it runs the version published before your fix. Your save creates a draft,333and the draft is not live. The published version keeps running, broken, until334somebody publishes the fix.335 336For a repair on a published workflow:337 338- Telling the user the fix is not live yet is not an offer to publish. Say it.339- Do NOT report the workflow as fixed, live, running, or working in production340 while the published version is the older one. Say the fix is in the draft.341- `verify-built-workflow` returns `claim.liveState`. `live-stale` means the342 published version is older than the draft you just verified. The result also343 carries `liveStateNote`. Relay it.344- Without a claim, call `workflows(action="get", workflowId)` and compare345 `versionId` (the draft) with `activeVersionId` (the published version). They346 differ while the fix is not live. A null `activeVersionId` means the workflow347 is not published at all.348- Ask whether to publish the fix. Publish only after the user agrees.349- Name the version in a retest invitation: the draft, or the published version.350 "Send another email to test it" is wrong when the fix is still a draft — the351 test would run the broken version and look like the fix failed.352 353## After build-workflow succeeds354 3551. Read `workflowId`, `workItemId`, `triggerNodes`, `verificationReadiness`,356 `setupRequirement`, and `postBuildFlow` from the tool output. If the output357 is missing a `workflowId`, explain that the build did not submit.358 - Before treating a saved workflow as done, inspect the persisted workflow359 with `workflows(action="get-as-code", workflowId)` or read the bound360 workspace source file, and compare the actual graph to the user's requested361 outcome. Build/save success only means a workflow was saved; it does not362 prove the saved workflow is good.363 - If the persisted workflow is missing the requested outcome, has an obvious364 dead-end draft shape, or the verification evidence is weak, load the365 `workflow-builder` skill and patch the same workflow with `build-workflow`366 using the existing `workflowId` and `workItemId`; then inspect and verify367 again.368 - If `verificationReadiness.status === "already_verified"`, do not repeat369 automatic verification. Read the saved claim before describing the workflow370 as verified. For tracked multi-trigger builds, follow the verification371 obligation until every trigger has a successful pass.372 373- If `verificationReadiness.status === "ready"`, call374 `verify-built-workflow` with the `workflowId`, the `workItemId` when you375 have it, and the trigger-appropriate `inputData` shape. When `triggerNodes`376 has more than one entry, call it once per trigger with `triggerNodeName`.377- If `verificationReadiness.status === "needs_setup"` and the persistent setup378 panel is enabled, first try `verify-built-workflow` when verification has not379 run. It can verify simulated paths or report that a simulation plan is380 unavailable. Then announce setup with `workflows(action="setup")`. Do not use381 a live execution to work around a blocker.382- If `verificationReadiness.status === "needs_setup"` and the persistent setup383 panel is disabled, call `workflows(action="setup")` with the workflow ID.384 The user configures the workflow through the inline setup card.385- If `verificationReadiness.status === "not_verifiable"`, do not infer386 lower-level verification conditions; use the readiness guidance to give a387 clear warning or manual-test note. This is a warning completion state, not388 a verified state and not an infinite blocker.389 3902. Judge coverage, not just status. A `verify-built-workflow` result with391 `success: true` but a non-empty `nodesNotReached` is **partial** evidence:392 the execution ended early (see `lastNodeExecuted` and `coverageNote`) and393 the listed nodes — including any planned simulations — never ran.394 - Most common cause: a lookup/query node returned zero items (n8n stops395 downstream nodes on empty item lists). If the dead-end is a Data Table396 lookup, insert a matching test row with `data-tables(action="insert-rows")`,397 re-run `verify-built-workflow`, and delete the test row afterwards. The same398 holds for data you seed anywhere else to unblock a run — it is yours to399 remove once the run is done (see "Cleaning up after a live test").400 - If you cannot seed the data source, report honestly: name which nodes401 were verified and which were not, and tell the user the unreached part402 needs a manual test. Do not start a live `executions(action="run")`403 yourself to reach those nodes; offer the user a test instead. Never claim404 end-to-end verification when `nodesNotReached` is non-empty — except for405 nodes another trigger's pass already reached, since per-trigger coverage406 is the union across passes.407 - If the unreached nodes sit behind IF/Switch logic controlled by a live or408 nondeterministic upstream node, and alternate-branch verification is part409 of this turn's goal, first try one source-file repair: add representative410 `output` fixtures to that upstream node, rebuild the same workflow, and411 re-run `verify-built-workflow` with `fixtureOverrides`. Only fall back to a412 manual-test note when you cannot safely patch the source or the repair413 budget is exhausted.414 - Relay `simulationNote` (nodes whose output was simulated) to the user415 whenever it is present.416 - Read `resolvedParameterWarnings`. A simulated node's preview is fixture417 data: it never proves an expression resolved. Each warning names a418 parameter that resolved to empty or threw on the real input — the usual419 causes are a trigger input that lacks the field (body-only webhook input420 for a `$json.query.*` expression) or a wrong expression. Fix the input421 shape or the expression, re-run, and never report that field as working422 while a warning stands. Each warning carries the execution ID that was423 checked. Use that ID with `executions(action="get-resolved-node-parameters")`424 to inspect the same input.425 - Read `skippedParameterChecks`. These nodes have unchecked dynamic fields.426 The list shows at most 20 checks. `skippedParameterCheckCount` includes427 omitted checks, which also leave dynamic fields unverified.428 State that limitation even if the run succeeded and no parameter warnings429 were returned. Do not request parameter values when sharing is disabled.4303. After verification handling, if `setupRequirement.status === "required"` and431 setup has not already run for this build, call `workflows(action="setup")`432 with the workflowId.4334. When `workflows(action="setup")` returns `announced: true`, summarize the434 panel state and end the turn. The live-test follow-up waits for a later user435 turn or Execute request. When the tool opens the inline setup card, the card is the436 user-visible surface. Do not tell the user to open the editor, use the canvas,437 or click a Setup button; the user does not need to navigate anywhere.4385. When `workflows(action="setup")` returns `deferred: true`, or reports439 `skippedByUser`, or applies only part of the card, respect the user's440 decision — do not retry with `credentials(action="setup")`, another441 `workflows(action="setup")` call, or any other setup tool. `partial: true`442 with `nodesStillNeedingSetup` is not permission to re-open the card in the443 same turn: report what remains as described in444 [Credentials the user skipped](#credentials-the-user-skipped).4456. After setup completes or is applied, follow446 [Mocked verification live-test follow-up](#mocked-verification-live-test-follow-up)447 when the latest verification evidence used mocks or simulations. If this448 follow-up is due, ask only whether the user wants the live test. Do not449 mention publishing or ask about the error workflow in the same response.450 If `credentialResolutionNote` says Gateway credits are depleted,451 that note wins: do not offer a live test.4527. Before your final summary, scan the **whole conversation** for live runs that453 already wrote test data into an external system — earlier turns included, not454 just this one. For each such record still sitting there, follow455 [Cleaning up after a live test](#cleaning-up-after-a-live-test): name it and456 offer to remove it. This is about data that **already exists** — a promise to457 clean up after some future run does not discharge it, and neither does the458 user's silence. If a later run failed, that says nothing about records an459 earlier successful run left behind; they are still there.4608. If testing has not already been offered or completed, ask whether the user461 wants to test the workflow. Skip this if `verify-built-workflow` already462 proved it works end-to-end with full coverage.4639. Only call `workflows(action="publish")` when the user explicitly asks to464 publish. Never publish automatically or proactively offer publishing before465 the publish-readiness requirement above is met. A repair of a workflow that466 is already published is the exception — follow467 [Fixing a workflow that is already published](#fixing-a-workflow-that-is-already-published).46810. After a direct new primary workflow is successfully published, follow469 [Error workflow follow-up](#error-workflow-follow-up).470 Do not replace this explicit opt-in with a generic "add471 anything else?", publish, or test question.472 473## Error workflow follow-up474 475This follow-up comes only after a direct new primary workflow is successfully published.476 477If you just built an Error Trigger workflow because the user opted into adding478one for a known target workflow, do not ask whether to build another error479workflow. Continue the publish-before-assign flow for the target workflow:480ask whether to publish the error workflow and set it on that target workflow,481then publish and assign only after the user approves.482 483After successfully publishing a direct new primary workflow,484ask once whether the user wants to build an error workflow for that workflow.485Use `ask-user` with a yes/no choice or a concise visible question. Do **not**486create an error workflow before the user opts in.487 488The opt-in must explicitly mention an error workflow and the target workflow489name. A generic follow-up like "Want me to add anything else?", "Want me to490publish it?", or "Want to test it?" does not satisfy this step.491 492Skip this follow-up when:493 494- The workflow you just built is itself an error workflow or starts with an495 Error Trigger.496- The build is a supporting workflow, repair, small edit, planned-task497 subtask, or workflow-level settings patch.498- The user already asked for an error workflow in the original request, already499 declined one, or the target workflow already has the desired error workflow500 set.501 502If the user says yes:503 5041. Load `workflow-builder` and build a separate error workflow using the user's505 requested notification destination. Keep the error workflow scoped to the506 target workflow the user opted in for.5072. Do not ask whether this new error workflow needs its own error workflow.5083. The error workflow must be published before it can be assigned. If the user509 has not already asked you to publish and attach it, ask whether to publish it510 and set it as the error workflow for the named target workflow. When the user511 agrees, call `workflows(action="publish")` for the error workflow and let the512 HITL approval card handle confirmation.5134. After publish succeeds, set the original workflow's workflow-level514 `settings.errorWorkflow` to the **error workflow's workflowId**. Do not use515 the published `activeVersionId`, workflow name, a placeholder, or a local SDK516 id. If you have the original source file, edit it; otherwise call517 `workflows(action="get-as-code", workflowId)` for the original workflow,518 write the returned code to a `.workflow.ts` file, add519 `.settings({ errorWorkflow: '<published-error-workflow-id>' })`, and call520 `build-workflow` for the original workflow. The workflow edit approval card521 is the HITL surface for this assignment.5225. Summarize the result with explicit per-workflow language: this error523 workflow was assigned only to the named target workflow. Mention that n8n has524 no global or instance-wide error workflow setting only when the user525 explicitly asked about, requested, or referenced global/instance-wide error526 workflow behavior.527 528## Mocked verification live-test follow-up529 530After workflow setup completes or is applied, if the latest verification for531that workflow used mocked credentials, simulated node output, fixture overrides,532temporary pin data, or another mocked input, ask whether the user wants a live533test without mocks. Ask only about the live test. Do not run it automatically.534An explicit test request in the current user input, including535`<workflow-test-request>`, already answers536this question. Run the requested test through `executions(action="run")`.537Do not offer publishing as an alternative or describe the workflow as ready to538use or publish.539 540If `credentialResolutionNote` says Gateway credits are depleted, that541note wins over this live-test offer: do not offer a live test. Tell the user542they must top up Gateway credits or add their own key on the node first.543 544If the user agrees, use the explicit live execution path (`executions(action="run")`545for a direct live run) and report the result separately from the earlier mocked546verification. If the live test fails, treat the workflow as unresolved and do547not offer publishing. If the user declines or defers, state what remains548untested, do not claim live end-to-end verification, and do not offer549publishing.550 551## Cleaning up after a live test552 553A live run against real credentials leaves **real artifacts** — a row in their554sheet, a message in their channel, a block on their page. Test data you created555is your mess, not theirs.556 557This applies to any live run in the conversation, **not only one from this558turn**. A test record written three turns ago is still on the user's page now,559and the debt is still yours — carry it forward until it is cleared or the user560declines. Undertaking to clean up after some _future_ run does not settle a561record that already exists, and a run that failed afterwards does not remove562what an earlier successful run wrote.563 564When a live test, or a verification you seeded data for, wrote/sent/changed565anything in an external system:566 5671. **Name what it left behind**, in the message that reports the run — or, for a568 record from an earlier turn, in your next response: which record, where, and569 how to recognise it ("a `[Test] …` to-do at the bottom of570 the toggle"). Read it back from the effect node's output rather than guessing.5712. **Offer to remove it yourself.** You can delete it the same way you wrote it —572 the target has an API and you can reach it with a workflow. When no node or573 tool does it directly, build a **one-off cleanup workflow**; that is exactly574 what `one-off-operations` is for. Never present manual deletion as how this575 gets resolved, and never claim you have no way to delete it — "I don't have a576 delete tool for X" is false whenever X has a write API you just used. Noting577 that the user _could_ also remove it by hand is fine only alongside your own578 offer.5793. **Ask before deleting.** Removal is destructive, so it goes through the usual580 approval gate. Never clean up silently — something labelled "test" may still581 be data the user wants.5824. **Don't stack test data.** Do not offer another live run against the same583 target while an earlier test artifact is still sitting there. Clear it first,584 or say plainly that the next run will add a second one.585 586If the user declines, note that the item is still there and move on — don't587re-ask.588 589**Not every write is test data.** When the live run _was_ the point — a one-off590operation whose whole purpose is the effect (see `one-off-operations`) — what it591wrote is the deliverable. There you offer to clean up the _workflow_, never the592result.593 594## Claiming success595 596For tracked multi-trigger builds, `claim` combines the saved successful passes.597A `verified` claim requires every trigger to pass and real coverage for every planned node.598Verify `claim.pendingTriggers` within the attempt limit. `nodesNotReached`599outside the claim describes only the current trigger's branch.600 601`verify-built-workflow` returns a `claim`, and its `level` decides what you may602say:603 604- `verified` — you may call the workflow verified, tested, or working.605- `partial`, `unproven`, or `failed` — you may NOT. Name what is unconfirmed606 instead.607 608`claim.liveState` decides separately whether you may call the workflow live. A609run always executes the draft, so `verified` says nothing about production:610 611- `live-stale` — the published version is older than the draft you verified.612 Do NOT call the workflow live, running, or working in production. Say the fix613 is in the draft, and see614 [Fixing a workflow that is already published](#fixing-a-workflow-that-is-already-published).615- `live-current` — the published version is the one you verified.616- `unpublished` — the workflow does not run in production at all.617 618**`success: true` does not mean verified.** It means the run ended without an619error, and a run with every write simulated also ends without an error. Read620`claim.level`, not `success`.621 622Nothing else tells the user how strong the claim is. Your message is the only623place they learn it, so name the unreached and simulated nodes yourself, and say624what stays unconfigured and what that means when the workflow runs.625 626Without a claim, do not tell the user a workflow is "fixed", "verified",627"tested", "working", or has "no errors" unless you have a passing628`executions(action="run")` or an inspected user-run execution that exercised the629path being claimed. Do not call a workflow "ready to use" or "ready to publish"630unless a passing execution met the publish-readiness requirement above. A631successful `build-workflow`/save, a static `workflows(action="validate")`, or632your own narration are NOT execution evidence. For a produced artifact (a file,633generated document, or Code-node output), read the real output before calling it634complete; do not infer correctness from the fact that a node ran. The same635applies to rows or records written to an external system: never make quantitative636claims ("22 rows written", "columns matched") that you did not read back from637the effect node's actual output (`executions(action="get-node-output")`) or from638the target system itself — a successful run status does not prove the _right639data_ was written, only that nodes ran. Output of a simulated or pinned node is640fixture data: never quote it as what the workflow produced, and never cite it as641proof that an expression resolved — use `resolvedParameterWarnings` or642`executions(action="get-resolved-node-parameters")` for that. If you could not run the643failing path or inspect the artifact, say so plainly — "I couldn't verify X644because Y" — and name what is unconfirmed. An honest "could not verify" beats an645unverified success claim.646 647## Credentials before build648 649Call `credentials(action="list")` first to know what's available. Build the650workflow immediately — the builder preserves explicit valid credentials and651auto-mocks missing or unselected ones. Do not ask whether to build now and set up652credentials later; building first and routing setup after verification is the653default path. Workflow verification is automatic from the build outcome; the654orchestrator handles workflow setup after verification when the saved workflow655still has mocked credentials or placeholders.656 657**Trust the build outcome over your own source file.** When `build-workflow`658returns `resolvedCredentialsByNode` (or `setupRequirement.status ===659"not_required"`), the saved workflow is already connected to existing660credentials — even if your source used an unresolved `newCredential()` call.661Do not ask the user to connect those credentials, do not offer the setup card662for them, and do not describe them as missing; at most mention which existing663credential is being used. Route credential setup only when the build outcome664reports mocked credentials or `setupRequirement.status === "required"`.665 666**Ask once when a service has multiple credentials of the same type.** If667`credentials(action="list")` shows more than one entry of the type a requested668integration needs (e.g. two `openAiApi` accounts, three Google Calendar669accounts), use `ask-user` with a single-select to let the user pick one before670building, and use the chosen credential name in the workflow code. Exception: the671user already named the credential in their message — use it directly. With a672single candidate, auto-apply and do not ask.673 674**Honor an explicit "create a new credential" request.** When the user asks for a675new credential of a type, never pick an existing one for them and never ask them676to choose among existing ones — not even when exactly one exists (the build would677otherwise attach it silently and skip setup entirely). Pass the credential type in678`preferNewCredentials` on both `build-workflow` and `workflows(action="setup")`679(or `preferNew: true` on the `credentials(action="setup")` entry). Setup then680opens on credential creation while still listing the existing credentials, so the681user can change their mind — say so in one short sentence rather than682re-litigating the choice. If they had skipped that card earlier, pass683`reopenSkipped` alongside it: `preferNewCredentials` decides what the card offers,684`reopenSkipped` decides whether the card comes back at all.685 686**Ask which auth type to use when a service supports more than one.**687`credentials(action="setup")` opens a picker locked to a single `credentialType`688— the user cannot switch auth types from there. So when689`credentials(action="search-types")` returns more than one auth option for a690service (e.g. `notionApi` and `notionOAuth2Api`, or `slackApi` and691`slackOAuth2Api`), use `ask-user` with a single-select to let the user pick the692auth type before calling `credentials(action="setup")`. List OAuth2 first and693present it as the recommended option. Exception: the user has clearly indicated694an auth type (e.g. "api key", "oauth", "personal token") — map it to the matching695`credentialType` and use it directly without asking.696 Discovery context
Discovered by repository scan. No exact path reference found in the snapshot’s root AGENTS.md.
