aaif-goose/goose · error

'activities' array element is not a string

Error message

'activities' array element is not a string

What it means

Thrown during recipe response parsing when "activities" is an array but contains at least one non-string element (as_str() returns None for that element). The model mixed objects, numbers, or nulls into the activities list.

Source

Thrown at crates/goose/src/agents/agent.rs:3859

        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");
                // If we can't get valid JSON, try string parsing
                // Use split_once to get the content after "Instructions:".
                let after_instructions = content
                    .split_once("instructions:")
                    .map(|(_, rest)| rest)
                    .unwrap_or(&content);

                // Split once more to separate instructions from activities.
                let (instructions_part, activities_text) = after_instructions
                    .split_once("activities:")
                    .unwrap_or((after_instructions, ""));

View on GitHub (pinned to 3810898a74)

Solutions

  1. Retry the recipe generation
  2. Use a stronger model
  3. Clean up / shorten the source conversation
  4. Fall back to hand-authoring the recipe
Defensive patterns

Strategy: retry

Validate before calling

// Rust — every activities element must be a string
let ok = json.get("activities").and_then(|a| a.as_array())
    .map(|a| a.iter().all(|e| e.is_string())).unwrap_or(false);
if !ok { /* regenerate */ }

Try / catch

// Rust — retry on element-type errors from generation
match generate_recipe(&agent, &conversation).await {
    Ok(r) => Ok(r),
    Err(e) if e.to_string().contains("array element is not a string") => retry_or_fallback(e),
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Model returns {"activities": [{"name": "step"}, "run tests"]} — an object element among strings — during recipe generation.

Common situations: Models emitting structured activity objects with extra metadata; mixed-language outputs; partial JSON degradation on long generations.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/c510744f63cd5873. Report an issue: GitHub.