Recipes · Chapter 42 of 69
Write Your First Workflow Recipe
Write a Kiro workflow recipe in .kiro/workflows/ that implements a change, reviews it with two parallel agents, and loops until a JSON verdict says APPROVED. Validate it, run it in the IDE and CLI, and fix the usual problems.
All levels 7 min read last reviewed 2026-10-04
◎ Learning objective
Save a small implement-review-loop recipe under .kiro/workflows/, validate it, launch it from the IDE or CLI, and read the run's evidence when it finishes.
A recipe is a small JSON or YAML file that tells Kiro’s runtime which agents to run, in what order, and when to stop. This one implements a change, has two reviewers look at it independently, merges their findings into a verdict, and repeats until the verdict is APPROVED or three attempts are used up.
When to use this
Use this when a change is big enough to deserve a separate reviewer but you do not want to supervise the review yourself, and when you want to learn the recipe format with something that exercises repeat, parallel, artifacts, and a stop condition in one file. It is not for a one-line fix; a loop with four agent steps per iteration costs more credits than a chat session, so start with a small task.
The recipe uses only agents Kiro ships for workflows. Swap in your own custom agent once you want tighter tools or a different model for a step.
Steps
-
Turn workflows on in the client you will use. IDE: in Agent Focus, Workspace Configuration → Workflows → enable (
kiroAgent.workflows.enabled), then start a new chat. CLI V3:/settings→ Features → Workflows, then exit and restart the CLI. Web: Settings → Workflows → Enable workflows. If the option is missing, the feature is not available for your account yet. -
Save the recipe. The file must sit in
.kiro/workflows/and end in.workflow.json(or.workflow.yaml/.workflow.yml)..kiro/workflows/implement-and-review.workflow.json{ "name": "implement-and-review", "description": "Implement a change, review it twice independently, loop until approved", "inputs": { "task": "prompt" }, "steps": [ { "type": "repeat", "id": "review-loop", "maxIterations": 3, "onMaxIterations": "pause", "stopCondition": { "fileCheck": { "path": ".kiro/workflow-output/review.json", "jsonPath": "verdict", "value": "APPROVED" } }, "steps": [ { "type": "step", "id": "implement", "agent": "wf-coder", "artifacts": { "summary": ".kiro/workflow-output/summary.md" }, "prompt": "Implement this change in the current workspace: {{task}}\n\nIf .kiro/workflow-output/review.json exists and its verdict is REVISE, address its findings first. Run the relevant tests. Do not commit. Write .kiro/workflow-output/summary.md listing changed files, tests run, and remaining risks, then finish with send_message severity success." }, { "type": "parallel", "id": "reviews", "joinPolicy": "all", "branches": [ { "type": "step", "id": "review-correctness", "agent": "semantic_reviewer", "artifacts": { "review_correctness": ".kiro/workflow-output/review-correctness.md" }, "prompt": "Review the uncommitted changes for correctness and missing tests, using {{artifacts.summary}} as your map. Do not edit code. Write your findings to .kiro/workflow-output/review-correctness.md." }, { "type": "step", "id": "review-safety", "agent": "semantic_reviewer", "artifacts": { "review_safety": ".kiro/workflow-output/review-safety.md" }, "prompt": "Review the uncommitted changes for security and error handling, using {{artifacts.summary}} as your map. Do not edit code. Write your findings to .kiro/workflow-output/review-safety.md." } ] }, { "type": "step", "id": "aggregate", "agent": "wf-review-aggregator", "artifacts": { "review": ".kiro/workflow-output/review.json" }, "prompt": "Read {{artifacts.review_correctness}} and {{artifacts.review_safety}}. Write .kiro/workflow-output/review.json with a verdict field of APPROVED or REVISE and a findings array, deduplicated, with corroborated issues first." } ] } ] } -
Read the recipe against the rules before you run it, because every one of them is checked:
taskis declared underinputs, so{{task}}resolves. An undeclared bare variable stays as literal text and only warns.- Each node has a unique
id. Therepeathas a finitemaxIterations, astopCondition, and anonMaxIterationsofpause, so a stuck loop hands you a decision instead of spending indefinitely. - The reviewers are inside
parallel, so they read{{artifacts.summary}}from the earlierimplementstep rather than{{previous.output}}, which is not allowed in a branch. Files cross step boundaries as artifacts; relative paths resolve from the workspace root. aggregatereads both review artifacts and writes the JSON thefileCheckreads. Kiro evaluates the condition after each iteration, so the loop always runs at least once..kiro/workflow-output/is just a folder inside the workspace, the one the docs’ own examples use. Any workspace path works; one outside every workspace root fails the node.
-
Validate it. Ask Kiro in the chat:
Run validate_workflow on .kiro/workflows/implement-and-review.workflow.json. Report every error and warning, and do not launch the workflow.Fix anything it reports. A pass means the file is well formed, not that the run can start: the validator does not check agent names or watch handlers. Kiro checks those when it creates the run.
-
Launch it with a small, real task.
IDE. Ask in the parent chat: “Run the
implement-and-reviewrecipe. Task: add input validation to the signup form’s email field.” Kiro launches the run in the background and the chat stays free.CLI V3.
/workflow run implement-and-review --task "add input validation to the signup form's email field"Omit
--taskand Kiro opens a form for it.Web. Upload the file with Upload workflow (one recipe per upload) under Settings → Workflows, then ask Kiro in a cloud session to run it and describe the task.
-
Follow the run. In the IDE, open Workflows above the parent chat, expand the run, and select a step to open its Workflow step tab with the agent’s session and a Message this step’s agent field. In the CLI, the full-screen monitor shows the step tree and active-step output;
/workflowopens history if you leave it, and/workflow status <workflowId>prints the status of a run you know. In Web, open Workflows beside the chat and select a step. -
If a step pauses with a question (it called
send_messagewith severitywarning), answer in that step’s own session: the Workflow step tab in the IDE, or select the step and presssin the CLI monitor. A plain message in the parent chat is a conversation with the main agent, not a reply to the step, unless you ask the main agent to pass it on.
Check it worked
Three things should be true when the run reports completed. The run’s status is completed, not paused at the iteration cap. .kiro/workflow-output/review.json exists and its verdict is APPROVED, which is what ended the loop. And the parent chat has the handoff: ask the main agent to summarise the run if it has not already, and it can name the workflow ID, the steps and loop iterations completed, the files changed, and what was verified. Then run git status: the implementation is in your working tree and uncommitted, because the prompt said so.
To see the loop actually loop, give it a task a reviewer is likely to reject, such as a change with no tests, and watch iteration two of implement pick up the findings from review.json.
Common problems
- The recipe does not appear, or
/workflow rundoes not know the name. Check the folder and suffix:.kiro/workflows/and.workflow.json. In the CLI, workflow commands are set when the process starts, so restart after enabling. In the IDE, an untrusted workspace does not load recipes until you trust it. If two files share a stem with different suffixes, the JSON one wins and the other is reported as a conflict. - A prompt shows a literal
{{task}}. The input was not declared, or not supplied at launch. - A step fails on an artifact or output template. The producer must run before the consumer: never reference a later sibling or another parallel branch, and never use
{{previous.output}}as the first node of a container or inside a branch. - The loop reaches the cap every time. Open
review.json. ThefileCheckneeds valid JSON, the exact keyverdict, and the exact valueAPPROVED; anything else, including a missing file, counts as no match. Tighten theaggregateprompt if the agent is writing a different shape. - Resume pauses again immediately. A repeat paused at its cap has spent its budget; Resume does not add iterations. Stop the run, raise the cap or fix the stop condition, and launch again.
- Validation passed but the run would not start. Check the agent names and your model access; those are runtime checks the standalone validator cannot do.
- You stopped the run and files are half changed. Stop does not undo edits. Inspect the workspace and revert with git before relaunching.
- The reviewers took as long as running them one after another. Expected.
parallelbuys isolation and a join policy, not a shorter wall clock.
Related
- Workflows explains the five ideas behind a recipe and how to enable the feature per client.
- Build a read-only reviewer agent is a good replacement for
semantic_reviewerwhen you want to control the reviewer’s tools yourself. - Create a custom agent makes any step agent you like, with its own model and tool set.
Frequently asked questions
How do I write a Kiro workflow recipe?
Create a file under .kiro/workflows/ ending in .workflow.json or .workflow.yaml. Give it a name, declare any inputs your prompts use as template variables, and fill the steps array with nodes. A step names an agent and a prompt; repeat loops a group with a maxIterations cap; parallel runs branches with a join policy. Ask Kiro to run validate_workflow on the file, then launch it.
How do I run a workflow in Kiro CLI?
Enable Workflows under /settings → Features and restart the CLI. Then run /workflow run <recipe-name> --task "what to do". If you leave out a declared input, Kiro opens a form to collect it. Follow the run in the monitor, or open /workflow later to find it in history.
Which agents can a workflow step use?
A workflow-capable agent: one of the agents Kiro bundles for workflows (wf-planner, wf-coder, wf-design, wf-design-reviewer, wf-review-aggregator, wf-pr-submitter, wf-pr-responder, wf-auto-researcher, semantic_reviewer) or a custom agent defined in .kiro/agents/. A built-in sub-agent is not valid as a step agent.
Why does my workflow loop stop at the cap even though the work looks done?
The stop condition did not match. For a fileCheck, Kiro reads the JSON file at the path, compares the value at jsonPath with the expected value, and treats a missing file, invalid JSON, missing path, or mismatch as not matched. Open the file and check the exact key and value the producing step wrote.
☰ Chapter summary
- A recipe is a JSON or YAML file in .kiro/workflows/ named *.workflow.json, *.workflow.yaml, or *.workflow.yml, with a name, optional inputs, and a steps tree.
- Node types are step, sequence, repeat, parallel, and watch; a step needs id, agent, and prompt, and the agent must be workflow-capable such as wf-coder or a custom agent in .kiro/agents/.
- Pass files between steps as artifacts and short text as captured output; inside a parallel branch never use previous.output.
- Give every repeat a finite maxIterations, a machine-readable stopCondition such as a fileCheck on a JSON verdict, and a deliberate onMaxIterations.
- Ask Kiro to run validate_workflow on the file before launching; validation cannot check agent names or watch handlers, which Kiro checks when the run is created.
- Launch by asking Kiro in the IDE chat, or with /workflow run <name> --task "..." in CLI V3; follow the run in the Workflows area or the CLI monitor.
All chapter summaries are collected on the revision page.
Related chapters
- ConceptsWorkflowsKiro workflows run a multi-step, multi-agent plan in the background while you keep chatting. What a recipe is, how to enable workflows per client, the bundled recipes, and what they cost.
- ConceptsCustom AgentsCustom agents are scoped versions of Kiro with their own prompt, tools, and model. File formats, the tools field, scopes, and how to create one.
- RecipesBuild a Read-Only Reviewer AgentCreate a Kiro agent that can read your codebase but cannot write or run commands, then back the ceiling with deny rules in permissions.yaml.
- RecipesCreate a Custom AgentCreate a Kiro custom agent as a Markdown file in .kiro/agents/, set its tools field, and switch to it mid-session or with kiro-cli --agent.
- Core knowledgeCredits & PricingKiro's plans and credits explained: Free $0/50, Pro $20/1,000 up to Power $200/10,000, what a credit buys, model multipliers, and how to avoid overage.