{"record":{"id":"5d6f02d718ce649f","repo":"charmbracelet/crush","slug":"failed-to-refresh-mcp-resources-w","errorCode":null,"errorMessage":"failed to refresh MCP resources: %w","messagePattern":"failed to refresh MCP resources: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":416,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to refresh MCP prompts: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to refresh MCP prompts: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// MCPRefreshResources refreshes resources for a named MCP client.\nfunc (c *Client) MCPRefreshResources(ctx context.Context, id, name string) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/mcp/refresh-resources\", id), nil,\n\t\tjsonBody(struct {\n\t\t\tName string `json:\"name\"`\n\t\t}{Name: name}),\n\t\thttp.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to refresh MCP resources: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to refresh MCP resources: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// GetAgentSessionQueuedPrompts retrieves the number of queued prompts for a\n// session.\nfunc (c *Client) GetAgentSessionQueuedPrompts(ctx context.Context, id string, sessionID string) (int, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/agent/sessions/%s/prompts/queued\", id, sessionID), nil, nil)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to get session agent queued prompts: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn 0, fmt.Errorf(\"failed to get session agent queued prompts: status code %d\", rsp.StatusCode)","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L398-L434","documentation":"MCPRefreshResources POSTs to /workspaces/{id}/mcp/refresh-resources and wraps any transport-level error from c.post with this message. It means the HTTP request to the server failed before a response status could be evaluated (connection failure, timeout, invalid URL, canceled context). The underlying cause is always wrapped and available via errors.Unwrap.","triggerScenarios":"Calling MCPRefreshResources(ctx, workspaceID, name) when the server is unreachable, the workspace ID is malformed/empty producing a bad URL, the context is canceled/timed out, or a proxy/DNS failure occurs during c.post.","commonSituations":"Dev server not running or restarted mid-session; wrong base URL or port in client configuration; network drops in CI; passing a workspace ID containing characters needing escaping.","solutions":["Check that the crush/opencode server is running and the client base URL points at the correct host/port","Verify the workspace ID passed is valid and URL-safe","Retry with a fresh context; add a timeout appropriate for the refresh call","Inspect the wrapped cause with errors.Unwrap / %v of the returned error to identify the transport failure"],"exampleFix":"// before\nerr := client.MCPRefreshResources(ctx, wsID, \"my-mcp\")\n// after\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()\nif err := client.MCPRefreshResources(ctx, wsID, \"my-mcp\"); err != nil {\n\tlog.Printf(\"refresh failed: %v\", errors.Unwrap(err))\n}","handlingStrategy":"retry","validationCode":"if wsID == \"\" { return fmt.Errorf(\"workspace ID required before MCPRefreshResources\") }\nif u, err := url.Parse(baseURL); err != nil || u.Host == \"\" { return fmt.Errorf(\"invalid server base URL\") }","typeGuard":"func isTransportErr(err error) bool {\n\tvar ne net.Error\n\treturn errors.As(err, &ne) || errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) || errors.Is(err, syscall.ECONNREFUSED)\n}","tryCatchPattern":"err := client.MCPRefreshResources(ctx, wsID, name)\nvar ne net.Error\nif errors.As(err, &ne) || errors.Is(err, context.DeadlineExceeded) {\n\t// transient: retry with backoff\n}","preventionTips":["Health-check the server before calling client methods","Use context.WithTimeout so hangs fail fast","Validate and URL-escape workspace IDs","Log errors.Unwrap(err) to capture the transport root cause"],"tags":["network","http-client","mcp"],"backgroundTag":"http-request-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}