How to Configure Goose Recipes with Parameters and Sub-Recipes

To configure Goose recipes with parameters and sub-recipes, define a top-level parameters array for dynamic inputs and invoke nested workflows using the subrecipe activity type with explicit values mappings and execution flags.

Goose recipes in the block/goose repository are YAML-based workflow definitions that become truly powerful when you configure them with dynamic parameters and reusable sub-recipes. By combining these two features, you can build modular AI agent pipelines that adapt to user input and execute complex tasks across multiple nested files according to the source documentation.

Defining Parameters for Dynamic Recipe Execution

Parameters turn static recipes into adaptable templates. In documentation/docs/tutorials/recipes-tutorial.md (lines 62‑66), the schema defines parameters as a top-level array where each entry declares a name, description, data type, and requirement level.

Parameter Schema and Supported Types

Goose enforces strict typing for recipe inputs. As documented in documentation/docs/guides/recipes/recipe-reference.md (lines 357‑360), you must specify one of the following types:

  • String – Free-form text input.
  • Number – Numeric values for calculations or counts.
  • Boolean – True/false flags.
  • Select – A predefined list of options with an options array.
  • File – Path references to local files.
  • User-prompt – Dynamic text captured from the user at runtime.

Optional parameters must include a default value, while required parameters omit this field to force user entry.

Jinja-Style Substitution Syntax

Once declared, reference parameters anywhere in your recipe using Jinja-style syntax. According to documentation/docs/guides/recipes/recipe-reference.md (lines 294‑295), the engine replaces {{ parameter_name }} placeholders with actual values during execution, whether they appear in prompts, instructions, or activity configurations.

User Input and CLI Overrides

When launching from Goose Desktop, a Recipe Parameters dialog automatically renders input fields for every required and optional parameter. For automated pipelines, pass values via the command line using the syntax shown in documentation/docs/guides/goose-cli-commands.md (lines 388‑390):

goose run recipe.yaml --params destination=Paris --params days=7

Composing Workflows with Sub-Recipes

Sub-recipes enable modular design by allowing one recipe to invoke another. This pattern, documented in documentation/docs/guides/recipes/subrecipes.md, supports deep nesting and parallel execution.

Invoking Child Recipes with the Subrecipe Activity

To call another recipe, add an activity with type: subrecipe and specify the target file path in the recipe field. As shown in documentation/docs/guides/recipes/subrecipes.md (lines 25‑33), you can pre-set the child’s parameters using a values map:

activities:
  - type: subrecipe
    recipe: "subrecipes/data_extract.yaml"
    values:
      source_file: "{{ input_file }}"

Parameter Precedence and Context Flow

Sub-recipes receive parameters through two channels. The documentation in documentation/docs/guides/recipes/subrecipes.md (lines 36‑38) clarifies the precedence:

  1. Explicit values – Entries in the parent’s values map take highest priority.
  2. Context extraction – The agent can pull values from conversation history or previous sub-recipe results, but these yield to explicit mappings.

Controlling Execution Mode

By default, Goose executes independent sub-recipes in parallel to maximize throughput. To force sequential execution when calling the same recipe multiple times with different parameters, set sequential_when_repeated: true as detailed in documentation/docs/tutorials/subrecipes-in-parallel.md (lines 26‑28). This prevents race conditions in workflows where later steps depend on earlier results.

Deep nesting is fully supported; parallel branches automatically schedule across the dependency graph unless explicitly serialized, enabling complex patterns like concurrent data extraction followed by a single merge step (lines 45‑47).

Complete Configuration Example

Below is a production-ready recipe demonstrating both parameters and sub-recipes. Save this as workflow_recipes/travel_planner.yaml:

title: Travel Planner
description: Plan a trip using user-provided destination and duration.
parameters:
  - name: destination
    description: Where the user wants to travel
    type: string
    required: true
  - name: days
    description: Length of the trip in days
    type: number
    required: true
activities:
  - type: subrecipe
    recipe: "subrecipes/flight_search.yaml"
    values:
      destination: "{{ destination }}"
  - type: subrecipe
    recipe: "subrecipes/hotel_search.yaml"
    values:
      destination: "{{ destination }}"
      days: "{{ days }}"
    sequential_when_repeated: true
  - type: prompt
    prompt: |
      Summarize the travel plan for {{ destination }} ({{ days }} days) using the flight and hotel results above.

The parent defines two required parameters, injects them into flight and hotel sub-recipes via the values map, and forces the hotel search to wait for flight completion using the sequential flag.

Summary

  • Declare a parameters array at the top of your recipe file to accept dynamic inputs, specifying types, descriptions, and requirement levels as defined in documentation/docs/guides/recipes/recipe-reference.md.
  • Reference parameters throughout your workflow using {{ parameter_name }} syntax for automatic substitution at runtime.
  • Invoke modular logic via the subrecipe activity, passing explicit parameter values through the values map to override context-based inference.
  • Control execution concurrency with the sequential_when_repeated flag; omit it for parallel execution or set it to true to enforce sequential processing.

Frequently Asked Questions

What parameter types does Goose support?

Goose supports string, number, boolean, select (with predefined options), file (path references), and user-prompt (runtime text capture) types. Optional parameters must provide a default value, while required parameters force user entry without defaults, as specified in documentation/docs/guides/recipes/recipe-reference.md (lines 357‑360).

How do I pass parameters to a sub-recipe from its parent?

Use the values map inside the subrecipe activity definition. Entries in this map take precedence over context-based extraction, ensuring the child recipe receives exactly the data specified by the parent workflow according to documentation/docs/guides/recipes/subrecipes.md (lines 36‑38).

Can I force sub-recipes to run sequentially instead of in parallel?

Yes. Set sequential_when_repeated: true on the sub-recipe activity. By default, Goose runs independent sub-recipes in parallel for performance, but this flag forces sequential execution when you need to prevent race conditions or ensure data dependencies resolve in order, as documented in documentation/docs/tutorials/subrecipes-in-parallel.md (lines 26‑28).

How do I provide parameter values when running a recipe from the command line?

Use the --params flag followed by key=value pairs. You can repeat this flag multiple times to set several parameters at once, as shown in documentation/docs/guides/goose-cli-commands.md (lines 388‑390). For example: goose run recipe.yaml --params city=London --params budget=1000.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →