-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Bug: Scheduler panics with unwrap() if recipe YAML has neither prompt nor instructions #7431
Copy link
Copy link
Closed
Description
Bug Description
The scheduler's execute_job function panics at runtime when a recipe YAML file contains neither a prompt nor instructions field. The CLI path does not validate recipe content when scheduling — only the cron expression is validated.
Affected Code
File: crates/goose/src/scheduler.rs, lines 781-785
let prompt_text = recipe
.prompt
.as_ref()
.or(recipe.instructions.as_ref())
.unwrap(); // panics if both are NoneRecipe loading (lines 724-735) has no validation:
let recipe: Recipe = {
let extension = recipe_path.extension()...;
match extension.as_str() {
"json" | "jsonl" => serde_json::from_str(&recipe_content)?,
_ => serde_yaml::from_str(&recipe_content)?,
}
};
// No call to validate_recipe_template_from_content()CLI path (crates/goose-cli/src/commands/schedule.rs) only validates cron:
validate_cron_expression(&cron)?; // only validates cron
// recipe content is NOT parsed or validatedImpact
- A user creates a minimal recipe YAML (e.g., just
extensions:andactivities:withoutpromptorinstructions) goose schedule addaccepts it without error- When the cron job fires, the scheduler thread panics
- The panic is silent — no user-visible error at schedule time, only a crash at execution time
- The
validate_prompt_or_instructionsfunction exists incrates/goose/src/recipe/validate_recipe.rsbut is never called by the scheduler
Steps to Reproduce
- Create a recipe file
test.yaml:extensions: - developer activities: - type: ask
- Schedule it:
goose schedule add --id test --cron "0 * * * *" --recipe test.yaml - Wait for the cron to fire (or manually trigger)
- Observe: thread panic at
scheduler.rs:785
Proposed Solution
Add recipe content validation in execute_job after deserialization (line 735), before accessing prompt/instructions:
let recipe: Recipe = serde_yaml::from_str(&recipe_content)?;
// Add validation
if recipe.prompt.is_none() && recipe.instructions.is_none() {
return Err(anyhow::anyhow!(
"Recipe must specify at least one of `instructions` or `prompt`"
));
}Or, call the existing validate_recipe_template_from_content function that already performs this check.
Happy to submit a PR for this fix.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels