--- name: post-build-flow description: >- Handles workflow verification and setup after workflow_builder_build_workflow succeeds, or when the message contains workflow-verification-follow-up or workflow-setup-required. Load after direct builds, when verificationReadiness requires action, or on orchestrator verify/setup follow-up turns. recommended_tools: - ask_user - workflow_builder_verify_built_workflow - get_workflow - get_workflow_as_code - setup_workflow - validate_workflow - publish_workflow - workflow_builder_build_workflow - list_executions - get_execution - run_workflow - run_workflow_step - debug_execution - get_execution_node_output - get_resolved_node_parameters --- # Post-Build Flow Use this skill after `workflow_builder_build_workflow` succeeds on a direct orchestrator build, especially when the build result contains `postBuildFlow.required: true`, or when the current message contains `` or ``. One-off builds (`postBuildFlow.reason: "direct-one-off-build-succeeded"`) hand off to the `one-off-operations` skill instead — verification is optional there and completion is a live run with read-back. If both sets of instructions are in context for a one-off build, the one-off flow wins. These instructions are in English, but user-visible text you write while following them stays in the user's conversation language. For trigger `inputData` shapes, read the workspace file `knowledge-base/reference/trigger-input-data-shapes.md` when a sandbox workspace is available, or load the `trigger-input-data-shapes` reference. ## Setup panel Use this section when the system prompt describes the persistent setup panel, setup returns `announced: true`, or the current user input contains ``. Otherwise, keep the setup card flow below. - Setup requirements can appear while the workflow is being built. The user can complete them immediately. Refer to the "setup panel" without a position or a claim that setup must wait until the build finishes. - Verify what the build can simulate before asking the user to finish setup. Missing credentials do not prevent this verification. Report which outputs were simulated. A simulated result does not prove a live connection. - When setup returns `announced: true`, summarize the open items and any validation warnings. End the turn. The user can complete setup in the panel while chat stays available. Do not wait, poll, or open a trigger-test card. - On a later user turn, trust `` over earlier setup results. If items settled, none remain open, and there are no validation warnings, verify the current saved configuration with `workflow_builder_verify_built_workflow`. It refreshes the credential plan. Report remaining simulations or connection failures. Do not claim live success from the earlier build result. - `` in the current user input means the user clicked Execute. A block in conversation history does not request another execution. Use the workflow ID in the current block. Inspect its current `` and read the saved workflow with `get_workflow_as_code`. Do not call `setup_workflow` for this precheck. It announces setup and ends the turn. If the target is absent from the state block, inspect its saved configuration. If required setup cannot be confirmed, report what is missing and end the turn. If required items remain open for this workflow, report them and end the turn without a live run. Otherwise, use `run_workflow` with suitable trigger input. The user has already requested this test; do not ask whether they want it. The execution tool still enforces its approval policy. Do not publish the workflow to test it. - Read the execution output and summarize what ran and what it returned. For failures, inspect `debug_execution`. Fix the same workflow when possible. Use the current saved source so panel edits are preserved. Report unresolved setup or failures in chat. Before another live run, inspect the successful effect nodes from the failed run. Follow [Cleaning up after a live test](#cleaning-up-after-a-live-test) for any artifacts they left behind. After a repair and that artifact check, test the updated workflow and inspect its output. Do not substitute mocked verification for the requested execution. A setup card that was already open keeps its apply and trigger-test resume flow. Its result is not a panel announcement unless it has `announced: true`. ## Verification follow-up When the current message contains ``, verify immediately from the payload's `obligation` — do not acknowledge first. If the obligation is `ready_to_verify` or `verifying`, call `workflow_builder_verify_built_workflow`. Do **not** call `setup_workflow` in this turn and do **not** declare the workflow finished if `outcome.setupRequirement.status === "required"` — setup is routed automatically as a separate `` step after verification. For a multi-trigger outcome, verify every trigger that does not yet have a recorded successful verification. Make all of these calls in this turn. ## Setup follow-up When the current message contains ``, your first action is to call `setup_workflow` with the `workflowId` from the payload. Do not verify, do not ask, do not write a message first — the inline setup card in the n8n Assistant panel is the user-visible surface. If the result has `announced: true`, use the persistent panel instructions above and end the turn. If it returns `deferred: true`, respect the user's choice and do not retry with any other setup tool. A result carrying `skippedByUser` names credentials the user already passed on: never re-open setup for those, in this turn or any later one — see [Credentials the user skipped](#credentials-the-user-skipped). After setup completes or is applied, follow [Mocked verification live-test follow-up](#mocked-verification-live-test-follow-up) if the payload or prior verification evidence says mocked credentials, simulated node output, fixture overrides, temporary pin data, or another mocked input was used. ### Choosing the credential type for a service Pick in this order: 1. **A dedicated credential type** (`slackApi`, `notionApi`, …) whenever one exists — search with `search_credential_types`. 2. **Simplified Custom Auth** (`httpTemplatedCustomAuth`) for any service without a dedicated type whose auth is expressible as header/query/body values — which covers API keys and bearer tokens (`Authorization: Bearer ` becomes `{"headers":{"Authorization":"Bearer {{api_key}}"}}`, not `httpBearerAuth`). Always provide a recipe (below) so the user only pastes their secret. 3. **Plain generic types** (`httpBasicAuth`, `httpDigestAuth`, `oAuth2Api`, …) only for what a template cannot express: basic auth's base64-encoded pair, digest's challenge-response, OAuth flows — or when the user explicitly asks for a specific plain type: an explicit user choice wins (setup accepts it with `allowPlainGenericAuth: true`). ### Credential recipes When the workflow authenticates a service through Simplified Custom Auth (`httpTemplatedCustomAuth`), include `credentialHints` in the same `setup_workflow` call, so the setup card pre-fills the credential and the user only pastes their secret. Before you compose the hints, load the `credential-recipe-research` reference and follow it. It lists every field and its rules. ### Credentials the user skipped Skipping is remembered for the whole conversation. A setup result may carry `skippedByUser` (nodes and credential types the user passed on), and a build outcome may carry `setupRequirement.status === "not_required"` with `reason: "skipped-by-user"`. In both cases the blocking setup card is off the table for those credentials — including after later edits, rebuilds, and `` steps. Asking again is the single most common complaint about this flow. Instead, in your normal message: - name what stays unconfigured and what happens at runtime (e.g. "the Slack post will fail until a channel is selected; the email still sends"), - offer to set it up whenever they want. Only once the user asks for a specific credential — "connect Slack now", "let's do the Slack setup", or picking it out of an offer you made — call `setup_workflow(reopenSkipped: ["slackApi"])`, naming just what they asked for so the rest stays skipped. A generic "yes" to an unrelated question is not an ask. Pass the `reopenWith` value the tool reported for that card, not the user's wording — a credential type for a credential card, a node name for one that was only missing a parameter. If nothing matches, setup answers with `unknown_reopen_target` and the list you can choose from; pick from it or tell the user what they named isn't part of this workflow. Don't fall back to re-offering, the user already asked. ## Publishing and testing **Publishing is never required for testing.** Both `run_workflow` and `workflow_builder_verify_built_workflow` inject `inputData` as the trigger's output — the workflow does not need to be active. Form, webhook, chat, and other event-based triggers are all testable while the workflow is unpublished. Never publish a workflow as a precondition for running it. **Webhook input must carry the fields the workflow reads.** A flat `inputData` becomes the request `body` only; `query`, `headers` and `params` stay empty. When any expression reads `$json.query.*`, `$json.headers.*` or `$json.params.*`, pass the request envelope `{ body: {...}, query: {...}, headers: {...}, params: {...} }` (or a `fixtureOverrides` entry on the trigger node). Otherwise the field resolves empty, the run still succeeds, and that field is unverified — say so instead of reporting it as working. Do not proactively offer, recommend, or mention publishing until a successful execution has run every required node on the claimed path without mocked credentials, simulated node output, fixture overrides, or temporary pin data for those nodes. Before you publish, offer publishing, count a run the user started as evidence, or repair a workflow that is already published, load the `publishing` reference and follow it. For post-build verification of workflows produced by `workflow_builder_build_workflow`, **always verify with `workflow_builder_verify_built_workflow`, never with raw `run_workflow`.** It reuses the build outcome simulation plan, mocked credentials, and temporary pin data, so destructive nodes are pinned and it is safe to call repeatedly. A raw `run_workflow` runs the workflow live with no pin data, and on a workflow you just verified it surfaces a redundant run-approval prompt to the user right after verification already executed the workflow. For follow-up requests like "verify again", call `workflow_builder_verify_built_workflow` with `workflowId` even if the original `workItemId` is not in context. For alternate deterministic scenarios, pass `fixtureOverrides` keyed by simulated node name instead of trying to force data through the trigger. **`run_workflow_step` is a debugging tool, not a verification tool.** It runs one node and tells you what that node returns. It says nothing about the rest of the chain, so it never settles a verification obligation and never turns "partial coverage" into "verified". Use it to inspect one node — most often with `reuseExecutionId` on a node that failed a real run — and keep verifying with `workflow_builder_verify_built_workflow`. A step run with `mockInput` proves even less: the result names the nodes whose output it invented in `mockedNodeNames`, and you must repeat that limitation in what you tell the user. **Reserve `run_workflow` for runs the user explicitly asked for** (e.g. "run it now", "execute it against my real data"). Never call it on your own to re-test, expand coverage, or "prove the full chain" of a workflow you just built or verified: re-run `workflow_builder_verify_built_workflow` instead — with `triggerNodeName` to reach another trigger's branch, or `fixtureOverrides` to reach another branch within one trigger's run — or report the partial coverage and let the user decide whether to run it. If `fixtureOverrides` is rejected with `invalid_fixture_override`, the target node was not classified as simulated in the build outcome. Do not retry the same override. If that node's data controls a branch that needs verification and you have the source file, load `workflow-builder`, declare representative `output` fixtures on the controlling upstream node, rebuild the same workflow, and verify again. **Never edit or copy a saved workflow to reach a branch.** Disabling, deleting, or reordering nodes to steer a test mutates the user's workflow and leaves it broken for as long as the test runs — if it is published, its triggers fire against the broken version. Building a throwaway second workflow is no better: the evidence is gathered against a copy that can drift from the workflow the user keeps, and the copy is left behind whenever the cleanup delete fails. For a workflow with more than one trigger (`triggerNodes` has multiple entries), **verify once per trigger**: - Pass `triggerNodeName` to `workflow_builder_verify_built_workflow` and call it once for each entry in `triggerNodes`. Naming no trigger verifies only the auto-detected one. An unresolvable name is rejected outright, so a rejected call means the name is wrong — re-read `triggerNodes`, never fall back to editing. - Each pass reports `nodesNotReached` only for its selected trigger's main-flow branch. Coverage is the **union** across successful passes. Run every trigger before you report a workflow coverage gap. Different triggers can select different outputs of a shared Switch or If node. - A failed rerun removes that trigger's earlier coverage. Verify that trigger again before you claim that the workflow is verified. - Report each trigger and whether its branch ran. Use the combined `claim` to describe the result (see "Claiming success"). - When the user asked for a live run, pass `triggerNodeName` to `run_workflow` the same way — one run per trigger — and report each branch's result. ## After workflow_builder_build_workflow succeeds 1. Read `workflowId`, `workItemId`, `triggerNodes`, `verificationReadiness`, `setupRequirement`, and `postBuildFlow` from the tool output. If the output is missing a `workflowId`, explain that the build did not submit. - Before treating a saved workflow as done, inspect the persisted workflow with `get_workflow_as_code(workflowId)` or read the bound workspace source file, and compare the actual graph to the user's requested outcome. Build/save success only means a workflow was saved; it does not prove the saved workflow is good. - If the persisted workflow is missing the requested outcome, has an obvious dead-end draft shape, or the verification evidence is weak, load the `workflow-builder` skill and patch the same workflow with `workflow_builder_build_workflow` using the existing `workflowId` and `workItemId`; then inspect and verify again. - If `verificationReadiness.status === "already_verified"`, do not repeat automatic verification. Read the saved claim before describing the workflow as verified. For tracked multi-trigger builds, follow the verification obligation until every trigger has a successful pass. - If `verificationReadiness.status === "ready"`, call `workflow_builder_verify_built_workflow` with the `workflowId`, the `workItemId` when you have it, and the trigger-appropriate `inputData` shape. When `triggerNodes` has more than one entry, call it once per trigger with `triggerNodeName`. - If `verificationReadiness.status === "needs_setup"` and the persistent setup panel is enabled, first try `workflow_builder_verify_built_workflow` when verification has not run. It can verify simulated paths or report that a simulation plan is unavailable. Then announce setup with `setup_workflow`. Do not use a live execution to work around a blocker. - If `verificationReadiness.status === "needs_setup"` and the persistent setup panel is disabled, call `setup_workflow` with the workflow ID. The user configures the workflow through the inline setup card. - If `verificationReadiness.status === "not_verifiable"`, do not infer lower-level verification conditions; use the readiness guidance to give a clear warning or manual-test note. This is a warning completion state, not a verified state and not an infinite blocker. 2. Judge coverage, not just status. A `workflow_builder_verify_built_workflow` result with `success: true` but a non-empty `nodesNotReached` is **partial** evidence: the execution ended early (see `lastNodeExecuted` and `coverageNote`) and the listed nodes — including any planned simulations — never ran. - Most common cause: a lookup/query node returned zero items (n8n stops downstream nodes on empty item lists). If the dead-end is a Data Table lookup, insert a matching test row with `data_tables(action="insert-rows")`, re-run `workflow_builder_verify_built_workflow`, and delete the test row afterwards. The same holds for data you seed anywhere else to unblock a run — it is yours to remove once the run is done (see "Cleaning up after a live test"). - If you cannot seed the data source, report honestly: name which nodes were verified and which were not, and tell the user the unreached part needs a manual test. Do not start a live `run_workflow` yourself to reach those nodes; offer the user a test instead. Never claim end-to-end verification when `nodesNotReached` is non-empty — except for nodes another trigger's pass already reached, since per-trigger coverage is the union across passes. - If the unreached nodes sit behind IF/Switch logic controlled by a live or nondeterministic upstream node, and alternate-branch verification is part of this turn's goal, first try one source-file repair: add representative `output` fixtures to that upstream node, rebuild the same workflow, and re-run `workflow_builder_verify_built_workflow` with `fixtureOverrides`. Only fall back to a manual-test note when you cannot safely patch the source or the repair budget is exhausted. - Relay `simulationNote` (nodes whose output was simulated) to the user whenever it is present. - Read `resolvedParameterWarnings`. A simulated node's preview is fixture data: it never proves an expression resolved. Each warning names a parameter that resolved to empty or threw on the real input — the usual causes are a trigger input that lacks the field (body-only webhook input for a `$json.query.*` expression) or a wrong expression. Fix the input shape or the expression, re-run, and never report that field as working while a warning stands. Each warning carries the execution ID that was checked. Use that ID with `get_resolved_node_parameters` to inspect the same input. - Read `skippedParameterChecks`. These nodes have unchecked dynamic fields. The list shows at most 20 checks. `skippedParameterCheckCount` includes omitted checks, which also leave dynamic fields unverified. State that limitation even if the run succeeded and no parameter warnings were returned. Do not request parameter values when sharing is disabled. 3. After verification handling, if `setupRequirement.status === "required"` and setup has not already run for this build, call `setup_workflow` with the workflowId. 4. When `setup_workflow` returns `announced: true`, summarize the panel state and end the turn. The live-test follow-up waits for a later user turn or Execute request. When the tool opens the inline setup card, the card is the user-visible surface. Do not tell the user to open the editor, use the canvas, or click a Setup button; the user does not need to navigate anywhere. 5. When `setup_workflow` returns `deferred: true`, or reports `skippedByUser`, or applies only part of the card, respect the user's decision — do not retry with `setup_credentials`, another `setup_workflow` call, or any other setup tool. `partial: true` with `nodesStillNeedingSetup` is not permission to re-open the card in the same turn: report what remains as described in [Credentials the user skipped](#credentials-the-user-skipped). 6. After setup completes or is applied, follow [Mocked verification live-test follow-up](#mocked-verification-live-test-follow-up) when the latest verification evidence used mocks or simulations. If this follow-up is due, ask only whether the user wants the live test. Do not mention publishing or ask about the error workflow in the same response. If `credentialResolutionNote` says Gateway credits are depleted, that note wins: do not offer a live test. 7. Before your final summary, scan the **whole conversation** for live runs that already wrote test data into an external system — earlier turns included, not just this one. For each such record still sitting there, follow [Cleaning up after a live test](#cleaning-up-after-a-live-test): name it and offer to remove it. This is about data that **already exists** — a promise to clean up after some future run does not discharge it, and neither does the user's silence. If a later run failed, that says nothing about records an earlier successful run left behind; they are still there. 8. If testing has not already been offered or completed, ask whether the user wants to test the workflow. Skip this if `workflow_builder_verify_built_workflow` already proved it works end-to-end with full coverage. 9. Only call `publish_workflow` when the user explicitly asks to publish, and load the `publishing` reference first. 10. After a direct new primary workflow is successfully published, load `error-workflows` and follow its error workflow follow-up. Do not replace this explicit opt-in with a generic "add anything else?", publish, or test question. ## Mocked verification live-test follow-up After workflow setup completes or is applied, if the latest verification for that workflow used mocked credentials, simulated node output, fixture overrides, temporary pin data, or another mocked input, ask whether the user wants a live test without mocks. Ask only about the live test. Do not run it automatically. An explicit test request in the current user input, including ``, already answers this question. Run the requested test through `run_workflow`. Do not offer publishing as an alternative or describe the workflow as ready to use or publish. If `credentialResolutionNote` says Gateway credits are depleted, that note wins over this live-test offer: do not offer a live test. Tell the user they must top up Gateway credits or add their own key on the node first. If the user agrees, use the explicit live execution path (`run_workflow` for a direct live run) and report the result separately from the earlier mocked verification. If the live test fails, treat the workflow as unresolved and do not offer publishing. If the user declines or defers, state what remains untested, do not claim live end-to-end verification, and do not offer publishing. ## Cleaning up after a live test A live run against real credentials leaves **real artifacts** — a row in their sheet, a message in their channel, a block on their page. Test data you created is your mess, not theirs. This applies to any live run in the conversation, **not only one from this turn**. A test record written three turns ago is still on the user's page now, and the debt is still yours — carry it forward until it is cleared or the user declines. Undertaking to clean up after some _future_ run does not settle a record that already exists, and a run that failed afterwards does not remove what an earlier successful run wrote. When a live test, or a verification you seeded data for, wrote/sent/changed anything in an external system: 1. **Name what it left behind**, in the message that reports the run — or, for a record from an earlier turn, in your next response: which record, where, and how to recognise it ("a `[Test] …` to-do at the bottom of the toggle"). Read it back from the effect node's output rather than guessing. 2. **Offer to remove it yourself.** You can delete it the same way you wrote it — the target has an API and you can reach it with a workflow. When no node or tool does it directly, build a **one-off cleanup workflow**; that is exactly what `one-off-operations` is for. Never present manual deletion as how this gets resolved, and never claim you have no way to delete it — "I don't have a delete tool for X" is false whenever X has a write API you just used. Noting that the user _could_ also remove it by hand is fine only alongside your own offer. 3. **Ask before deleting.** Removal is destructive, so it goes through the usual approval gate. Never clean up silently — something labelled "test" may still be data the user wants. 4. **Don't stack test data.** Do not offer another live run against the same target while an earlier test artifact is still sitting there. Clear it first, or say plainly that the next run will add a second one. If the user declines, note that the item is still there and move on — don't re-ask. **Not every write is test data.** When the live run _was_ the point — a one-off operation whose whole purpose is the effect (see `one-off-operations`) — what it wrote is the deliverable. There you offer to clean up the _workflow_, never the result. ## Claiming success For tracked multi-trigger builds, `claim` combines the saved successful passes. A `verified` claim requires every trigger to pass and real coverage for every planned node. Verify `claim.pendingTriggers` within the attempt limit. `nodesNotReached` outside the claim describes only the current trigger's branch. `workflow_builder_verify_built_workflow` returns a `claim`, and its `level` decides what you may say: - `verified` — you may call the workflow verified, tested, or working. - `partial`, `unproven`, or `failed` — you may NOT. Name what is unconfirmed instead. `claim.liveState` decides separately whether you may call the workflow live. A run always executes the draft, so `verified` says nothing about production: - `live-stale` — the published version is older than the draft you verified. Do NOT call the workflow live, running, or working in production. Say the fix is in the draft, and follow the `publishing` reference. - `live-current` — the published version is the one you verified. - `unpublished` — the workflow does not run in production at all. **`success: true` does not mean verified.** It means the run ended without an error, and a run with every write simulated also ends without an error. Read `claim.level`, not `success`. Nothing else tells the user how strong the claim is. Your message is the only place they learn it, so name the unreached and simulated nodes yourself, and say what stays unconfigured and what that means when the workflow runs. Without a claim, do not tell the user a workflow is "fixed", "verified", "tested", "working", or has "no errors" unless you have a passing `run_workflow` or an inspected user-run execution that exercised the path being claimed. Do not call a workflow "ready to use" or "ready to publish" unless a passing execution met the publish-readiness requirement above. A successful `workflow_builder_build_workflow`/save, a static `validate_workflow`, or your own narration are NOT execution evidence. For a produced artifact (a file, generated document, or Code-node output), read the real output before calling it complete; do not infer correctness from the fact that a node ran. The same applies to rows or records written to an external system: never make quantitative claims ("22 rows written", "columns matched") that you did not read back from the effect node's actual output (`get_execution_node_output`) or from the target system itself — a successful run status does not prove the _right data_ was written, only that nodes ran. Output of a simulated or pinned node is fixture data: never quote it as what the workflow produced, and never cite it as proof that an expression resolved — use `resolvedParameterWarnings` or `get_resolved_node_parameters` for that. If you could not run the failing path or inspect the artifact, say so plainly — "I couldn't verify X because Y" — and name what is unconfirmed. An honest "could not verify" beats an unverified success claim. ## Trigger URL Sharing After building a workflow that uses a trigger with an HTTP endpoint, share the full production URL with the user. Use the Webhook base URL and Form base URL from the `` block in the user's turn. Each trigger type has a distinct pattern: - **Webhook Trigger**: `{webhookBaseUrl}/{path}` (where `{path}` is the node's webhook path parameter). - **Form Trigger**: `{formBaseUrl}/{path}` (or `{formBaseUrl}/{webhookId}` if no custom path is set). Form Trigger lives under `/form/`, NOT `/webhook/` — they are separate URL prefixes. Do NOT use the Webhook base URL for Form Triggers. - **Chat Trigger**: how the end user reaches this workflow depends on the node's `public` parameter — pick the right guidance for the current value, do not default to sharing a URL. - **`public: false` (the default)**: there is NO end-user HTTP URL. Tell the user to open the workflow in the editor and click the **Open chat** button on the workflow canvas — that opens the built-in test chat. Do NOT share a webhook URL, and do NOT suggest flipping `public: true` just to enable testing — the in-editor chat is the intended testing path for private chat workflows. - **`public: true`**: the public chat URL is `{webhookBaseUrl}/{webhookId}/chat` — share it after the workflow is published. `{webhookId}` is the node's unique webhook ID; read it from the workflow JSON, never guess. End users can open this URL in a browser. The `/chat` suffix is unique to Chat Trigger — do NOT append it to Form Trigger or Webhook URLs. (Your own testing via `run_workflow` and `workflow_builder_verify_built_workflow` works regardless of `public` or publish state.) **These URLs are for sharing with the user only.** Do NOT hardcode them into workflow code or build specs unless the workflow actually needs to send or store its own public endpoint. ## Credential choices during setup These rules apply after the first build, while setup runs. Before the first build, do not ask about credentials: the builder preserves explicit valid credentials and auto-mocks missing or unselected ones. Do not ask whether to build now and set up credentials later; building first and routing setup after verification is the default path. **Trust the build outcome over your own source file.** When `workflow_builder_build_workflow` returns `resolvedCredentialsByNode` (or `setupRequirement.status === "not_required"`), the saved workflow is already connected to those credentials, even if your source used an unresolved `newCredential()` call. Route credential setup only when the build outcome reports mocked credentials or `setupRequirement.status === "required"`. **Let setup collect the choice when a service has multiple credentials of the same type.** The setup card lists every credential of that type, so the user picks one there. Do not ask this in chat or with `ask_user`. Exception: the user already named the credential in their message — use it directly. **Honor an explicit "create a new credential" request** with `preferNewCredentials` (see Credential Rules). Never ask the user to choose among existing credentials, not even when exactly one exists. Setup opens on credential creation and still lists the existing credentials, so the user can change their mind — say so in one short sentence. If they had skipped that card earlier, pass `reopenSkipped` alongside it: `preferNewCredentials` decides what the card offers, `reopenSkipped` decides whether the card comes back at all. **Ask which auth type to use when a service supports more than one** only for a standalone credential request: `setup_credentials` outside any workflow. That picker is locked to a single `credentialType`. So when `search_credential_types` returns more than one auth option for the service (e.g. `notionApi` and `notionOAuth2Api`), use `ask_user` with a single-select before the setup call. List OAuth2 first and present it as the recommended option. Exception: the user has clearly indicated an auth type (e.g. "api key", "oauth", "personal token") — map it to the matching `credentialType` without asking. In a workflow build, never ask about the auth type, before or after the build: leave an ambiguous auth type out of early setup, let the build pick it from the node definition, and let setup collect the credential.