aaif-goose/goose · error
instructions' is not a string
Error message
instructions' is not a string
What it means
Thrown during recipe response parsing when the JSON object contains "instructions" but its value is not a string (as_str() fails). The model returned instructions as an object, array, or number instead of a plain string.
Source
Thrown at crates/goose/src/agents/agent.rs:3847
content.len()
);
// the response may be contained in ```json ```, strip that before parsing json
let re = Regex::new(r"(?s)```[^\n]*\n(.*?)\n```").unwrap();
let clean_content = re
.captures(&content)
.and_then(|caps| caps.get(1).map(|m| m.as_str()))
.unwrap_or(&content)
.trim()
.to_string();
let (instructions, activities) =
if let Ok(json_content) = serde_json::from_str::<Value>(&clean_content) {
let instructions = json_content
.get("instructions")
.ok_or_else(|| anyhow!("Missing 'instructions' in json response"))?
.as_str()
.ok_or_else(|| anyhow!("instructions' is not a string"))?
.to_string();
let activities = json_content
.get("activities")
.ok_or_else(|| anyhow!("Missing 'activities' in json response"))?
.as_array()
.ok_or_else(|| anyhow!("'activities' is not an array'"))?
.iter()
.map(|act| {
act.as_str()
.map(|s| s.to_string())
.ok_or(anyhow!("'activities' array element is not a string"))
})
.collect::<Result<_, _>>()?;
(instructions, activities)
} else {
tracing::warn!("Failed to parse JSON, falling back to string parsing");View on GitHub (pinned to 3810898a74)
Solutions
- Retry the generation — shape errors are often nondeterministic
- Switch to a model known to follow goose's recipe prompt
- Trim the input conversation to reduce schema drift
- Hand-write the recipe YAML instead of generating it
Defensive patterns
Strategy: retry
Validate before calling
// Rust — check the field type before downstream parsing
let ok = json.get("instructions").map(|i| i.is_string()).unwrap_or(false);
if !ok { /* regenerate instead of failing */ } Try / catch
// Rust — same retry envelope as the other recipe JSON-shape errors
match generate_recipe(&agent, &conversation).await {
Ok(r) => Ok(r),
Err(e) if e.to_string().contains("is not a string") => retry_or_fallback(e),
Err(e) => Err(e),
} Prevention
- Prefer models that follow JSON schemas exactly for generation tasks
- Retry once before debugging — type confusion is often a one-off sampling failure
When it happens
Trigger: Model returns {"instructions": {"text": "..."}} or {"instructions": ["a", "b"]} — structured rather than scalar — during recipe generation.
Common situations: Models that over-structure output; prompt templates asking for 'detailed instructions' nudging the model into nested formats; JSON-schema-tuned models exporting every field as an object.
Related errors
- Missing 'instructions' in json response
- Missing 'activities' in json response
- 'activities' is not an array'
- 'activities' array element is not a string
- Invalid deeplink or recipe format
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/e10638649c3a153b.
Report an issue: GitHub.