aaif-goose/goose · error

Failed to serialize arguments: {}

Error message

Failed to serialize arguments: {}

What it means

Before invoking an extension prompt, goose converts the arguments map to a serde_json::Value. For the string-keyed, string-valued map used here, to_value is effectively infallible, so this error is a defensive wrap around serde_json::to_value's Result rather than a realistic failure mode; the inner error {e} would name the offending value.

Source

Thrown at crates/goose-cli/src/session/mod.rs:1997

    }

    /// Handle prompt command execution
    async fn handle_prompt_command(&mut self, opts: input::PromptCommandOptions) -> Result<()> {
        // name is required
        if opts.name.is_empty() {
            output::render_error("Prompt name argument is required");
            return Ok(());
        }

        if opts.info {
            match self.get_prompt_info(&opts.name).await? {
                Some(info) => output::render_prompt_info(&info),
                None => output::render_error(&format!("Prompt '{}' not found", opts.name)),
            }
        } else {
            // Convert the arguments HashMap to a Value
            let arguments = serde_json::to_value(opts.arguments)
                .map_err(|e| anyhow::anyhow!("Failed to serialize arguments: {}", e))?;

            match self.get_prompt(&opts.name, arguments).await {
                Ok(messages) => {
                    let start_len = self.messages.len();
                    let mut valid = true;
                    let num_messages = messages.len();
                    for (i, prompt_message) in messages.into_iter().enumerate() {
                        let msg = Message::from(prompt_message);
                        // ensure we get a User - Assistant - User type pattern
                        let expected_role = if i % 2 == 0 {
                            rmcp::model::Role::User
                        } else {
                            rmcp::model::Role::Assistant
                        };

                        if msg.role != expected_role {
                            output::render_error(&format!(
                                "Expected {:?} message at position {}, but found {:?}",

View on GitHub (pinned to 3810898a74)

Solutions

  1. Read the inner error {e} to identify which value failed to serialize
  2. Keep prompt arguments as string-to-string pairs as documented
Defensive patterns

Strategy: try-catch

Validate before calling

fn args_are_serializable(args: &HashMap<String, String>) -> bool {
    serde_json::to_value(args).is_ok()
}

Try / catch

let arguments = match serde_json::to_value(opts.arguments) {
    Ok(v) => v,
    Err(e) => {
        eprintln!("prompt arguments not JSON-serializable: {}", e);
        return Ok(());
    }
};

Prevention

When it happens

Trigger: Running a prompt with arguments (get_prompt path) where to_value returns Err — only conceivable after the arguments type changes to something not JSON-representable.

Common situations: Practically unreproducible with current types; would surface after an API change to the argument map's key or value types.

Related errors


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