goose icon indicating copy to clipboard operation
goose copied to clipboard

Bug Report: text_editor Tool Returns "Tool not found" Error - Missing name in Response

Open realDGK opened this issue 9 months ago • 3 comments

Installing Goose from the source.

The text_editor tool within the developer extension consistently fails with a "Tool not found" error, even when the tool is correctly invoked. After extensive debugging, I identified that the tool's handler functions were incorrectly returning a Vec<Content> directly, instead of a properly formatted response object that includes the tool's name. This caused the mcp-client to reject the response.

Steps to Reproduce:

  1. Set up a Goose AI environment using Docker Compose, as described in the documentation.

  2. Use the Docker service that runs the Goose AI core logic and the mcp-server (the service built from the goose-mcp crate)."

  3. Enable the developer extension.

  4. Attempt to use the text_editor tool with any command (e.g., create file /tmp/test.txt, then enter "hello" when prompted).

  5. The error "Tool not found: "" for request..." will appear.

Root Cause:

The text_editor_write, text_editor_view, text_editor_replace, and text_editor_undo functions in goose-mcp/src/developer/mod.rs were returning Result<Vec<Content>, ToolError>. The mcp-client expects a response object (likely a ToolResult struct, though I didn't find its precise definition in the readily available code) that includes a name field indicating the originating tool. Because this name field was missing, the client interpreted the response as coming from an unknown tool.

Affected Files and Functions:

goose-mcp/src/developer/mod.rs text_editor_write text_editor_view text_editor_replace text_editor_undo text_editor call_tool Temporary Fix:

Implemented a temporary fix by: Creating a ToolResult struct: defined the following struct in goose-mcp/src/developer/mod.rs:

Rust

#[derive(Debug)] struct ToolResult { name: String, status: String, value: Vec<Content>, }

Modifying the Handler Functions: changed the return type of text_editor_write, text_editor_view, text_editor_replace, text_editor_undo and text_editor to Result<ToolResult, ToolError>.

Then wrapped the Vec<Content> in an instance of this ToolResult struct, setting the name field to "developer__text_editor" and the status field to "success":

Rust

// Example from text_editor_write: async fn text_editor_write( &self, path: &PathBuf, file_text: &str, ) -> Result<ToolResult, ToolError> { // ... (rest of the function logic) ...

Ok(ToolResult {
    name: "developer__text_editor".to_string(),
    status: "success".to_string(),
    value: content_vec,
})

}

Did this for all of text_editor_write, text_editor_view, text_editor_replace, and text_editor_undo. and did similar changes for text_editor.

Modifying the call function updated the call_tool function to account for the change in return value from the text_editor tool:

Rust

fn call_tool(
    &self,
    tool_name: &str,
    arguments: Value,
) -> Pin<Box<dyn Future<Output = Result<Vec<Content>, ToolError>> + Send + 'static>> {
    let this = self.clone();
    let tool_name = tool_name.to_string();
    Box::pin(async move {
        match tool_name.as_str() {
            "shell" => this.bash(arguments).await,
            "text_editor" => {
                let result: ToolResult = this.text_editor(arguments).await?;
                Ok(result.value)
            },
            "list_windows" => this.list_windows(arguments).await,
            "screen_capture" => this.screen_capture(arguments).await,
            "image_processor" => this.image_processor(arguments).await,
            _ => Err(ToolError::NotFound(format!("Tool {} not found", tool_name))),
        }
    })
}

Environment:

Docker Compose setup (using the Goose AI provided configuration). the Docker service that runs the Goose AI core logic and the mcp-server (the service built from the goose-mcp crate)." service.

WSL 2 (Windows Subsystem for Linux) - though this is likely not directly relevant to the bug itself, it did affect file permissions initially, which was resolved with umask 0000.

Additional Notes:

This is a temporary fix. The correct solution would involve using the intended ToolResult type (or equivalent) from the mcp crates, if one exists.

I was unable to find the exact definition of the expected response structure in the code i had access to. Recommend checking other tools in the developer extension for similar issues

realDGK avatar Mar 11 '25 09:03 realDGK

@leedsjb we are already on it, we are rolling these on incremental basis to avoid broken URLs. You should expect them in the next release.

vamsi avatar Mar 10 '25 17:03 vamsi

@vamsi awesome - thank you!

leedsjb avatar Mar 10 '25 17:03 leedsjb

For cloud users looking for this functionality (my request is for self-hosted edition) this is available on cloud as of 4/3/25: https://plane.so/changelog/cloud?version=25.04.03.

leedsjb avatar Apr 09 '25 04:04 leedsjb

This is now implemented in v1.9.0 - thanks! https://plane.so/changelog/commercial#release-v1.9.0

leedsjb avatar May 26 '25 01:05 leedsjb