charmbracelet/crush · error
failed to decode MCP prompts: %w
Error message
failed to decode MCP prompts: %w
What it means
On a 200 response, ListMCPPrompts decodes the body into []proto.MCPPrompt. 'failed to decode MCP prompts: %w' means the JSON body does not match the expected prompt schema — typically a client/server version mismatch or an intermediary returning non-JSON content.
Source
Thrown at internal/client/config.go:335
var contents []MCPResourceContents
if err := json.NewDecoder(rsp.Body).Decode(&contents); err != nil {
return nil, fmt.Errorf("failed to decode MCP resource: %w", err)
}
return contents, nil
}
func (c *Client) ListMCPPrompts(ctx context.Context, id string) ([]proto.MCPPrompt, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/mcp/prompts", id), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to list MCP prompts: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to list MCP prompts: status code %d", rsp.StatusCode)
}
var prompts []proto.MCPPrompt
if err := json.NewDecoder(rsp.Body).Decode(&prompts); err != nil {
return nil, fmt.Errorf("failed to decode MCP prompts: %w", err)
}
return prompts, nil
}
// GetMCPPrompt retrieves a prompt from a named MCP server.
func (c *Client) GetMCPPrompt(ctx context.Context, id, clientID, promptID string, args map[string]string) (string, error) {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/mcp/get-prompt", id), nil, jsonBody(struct {
ClientID string `json:"client_id"`
PromptID string `json:"prompt_id"`
Args map[string]string `json:"args"`
}{ClientID: clientID, PromptID: promptID, Args: args}), http.Header{"Content-Type": []string{"application/json"}})
if err != nil {
return "", fmt.Errorf("failed to get MCP prompt: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return "", fmt.Errorf("failed to get MCP prompt: status code %d", rsp.StatusCode)
}View on GitHub (pinned to 7944b8e522)
Solutions
- Align client and server versions.
- Inspect the raw body (curl the endpoint) to confirm what was returned.
- Bypass/check proxies to rule out HTML injection.
- Update the client's proto.MCPPrompt types if the schema legitimately changed.
Example fix
// before
prompts, err := client.ListMCPPrompts(ctx, id)
// after
prompts, err := client.ListMCPPrompts(ctx, id)
if err != nil && strings.Contains(err.Error(), "failed to decode MCP prompts") {
return nil, fmt.Errorf("prompt schema mismatch — update the coder client to match server version: %w", err)
} Defensive patterns
Strategy: type-guard
Validate before calling
// check version compatibility once at startup
info, err := client.BuildInfo(ctx)
if err != nil {
return fmt.Errorf("cannot verify server compatibility: %w", err)
} Type guard
func isPromptDecodeError(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to decode MCP prompts")
}
// usage: if isPromptDecodeError(err) { /* version mismatch — do not retry blindly */ } Try / catch
prompts, err := client.ListMCPPrompts(ctx, id)
if isPromptDecodeError(err) {
// schema mismatch: update client types or server version; don't retry
return nil, fmt.Errorf("prompt schema mismatch with server: %w", err)
}
if err != nil { return nil, err } Prevention
- Upgrade the client whenever the server is upgraded.
- Treat decode errors as non-retryable and investigate the raw body.
- Confirm proxies return JSON, not HTML error pages.
- Add integration tests hitting a real server to catch schema drift early.
When it happens
Trigger: json.Decode error: schema drift in proto.MCPPrompt, HTML error page from a proxy, empty or truncated body despite 200.
Common situations: Upgraded Coder server with a changed prompt schema while the client is old; an ingress proxy returning HTML 200 pages; custom MCP servers emitting unexpected prompt fields is fine, but a wholly different body shape is not.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode MCP resource: %w
- failed to decode response: %w
- failed to decode MCP prompt response: %w
- failed to decode workspaces: %w
- failed to decode MCP pending auth: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/57d9b700ae6ed4ec.
Report an issue: GitHub.