aaif-goose/goose · error
Recipe build failed: {}
Error message
Recipe build failed: {} What it means
Thrown when RecipeBuilder::build() rejects the assembled recipe during LLM recipe generation. build() enforces three invariants (crates/goose/src/recipe/mod.rs:409): a title, a description, and at least one of prompt/instructions. The '{}' is one of those static messages ('Title is required', 'Description is required', or "At least one of 'prompt' or 'instructions' is required").
Source
Thrown at crates/goose/src/agents/agent.rs:3960
} else {
(
"Custom recipe from chat".to_string(),
"a custom recipe instance from this chat session".to_string(),
)
};
let recipe = Recipe::builder()
.title(title)
.description(description)
.instructions(instructions)
.activities(activities)
.extensions(extension_configs)
.settings(settings)
.author(author)
.build()
.map_err(|e| {
tracing::error!("Failed to build recipe: {}", e);
anyhow!("Recipe build failed: {}", e)
})?;
tracing::info!("Recipe creation completed successfully");
Ok(recipe)
}
}
fn recipe_conversation_history(messages: &Conversation) -> Vec<Message> {
// The recipe prompt has no turn-context instructions; drop the blocks.
messages
.agent_visible_messages()
.into_iter()
.filter(|message| !message.is_turn_context())
.collect()
}
#[cfg(test)]
mod tests {View on GitHub (pinned to 3810898a74)
Solutions
- Retry generation with a more descriptive conversation as the source
- Use a stronger model that reliably produces title and description
- If embedding, supply explicit title/description via the builder instead of relying on extraction
- Hand-author the recipe YAML with all required fields
Example fix
// before
Recipe::builder()
.instructions(instructions)
.activities(activities)
.build()?; // Err: Title is required
// after
Recipe::builder()
.title(title)
.description(description)
.instructions(instructions)
.activities(activities)
.build()? Defensive patterns
Strategy: validation
Validate before calling
// Rust — check builder invariants before calling build()
let ok = !title.trim().is_empty()
&& !description.trim().is_empty()
&& (!instructions.trim().is_empty() || !prompt.trim().is_empty());
if !ok { /* regenerate or fill in fields explicitly */ } Prevention
- Always set title, description, and instructions (or prompt) on RecipeBuilder — they are required
- Provide explicit title/description when generating from thin conversations
- Hand-author YAML for recipes you will reuse instead of regenerating
When it happens
Trigger: Recipe generation completes but the extracted title/description came out empty, or both instructions and prompt are absent (e.g. every parsing path produced nothing usable), so the final builder validation fails.
Common situations: Models returning an empty title/description; upstream parsing fallbacks yielding empty strings; conversations with no derivable subject (tiny or empty transcript).
Related errors
- {} recipe file is invalid: {}
- Directory '{}' does not exist
- Missing 'instructions' in json response
- instructions' is not a string
- Missing 'activities' in json response
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/a7135f31d3571aa0.
Report an issue: GitHub.