Tencent/WeKnora · error

failed to read resource: %w

Error message

failed to read resource: %w

What it means

ReadResource wraps any failure from the underlying MCP client's ReadResource RPC (including OAuth failures from oauthCall) with "failed to read resource: %w". checkErrorAndDisconnectIfNeeded is invoked first and may flag the connection as broken. The original error is preserved for errors.Is/As unwrapping.

Source

Thrown at internal/mcp/client.go:533

// ReadResource reads a resource from the MCP service
func (c *mcpGoClient) ReadResource(ctx context.Context, uri string) (*ReadResourceResult, error) {
	if !c.initialized {
		return nil, ErrNotConnected
	}

	req := mcp.ReadResourceRequest{
		Params: mcp.ReadResourceParams{
			URI: uri,
		},
	}

	result, err := oauthCall(ctx, c, func() (*mcp.ReadResourceResult, error) {
		return c.client.ReadResource(ctx, req)
	})
	if err != nil {
		c.checkErrorAndDisconnectIfNeeded(err)
		return nil, fmt.Errorf("failed to read resource: %w", err)
	}

	// Convert to our types
	contents := make([]ResourceContent, 0, len(result.Contents))
	for _, item := range result.Contents {
		if textContent, ok := mcp.AsTextResourceContents(item); ok {
			contents = append(contents, ResourceContent{
				URI:      textContent.URI,
				MimeType: textContent.MIMEType,
				Text:     textContent.Text,
			})
		} else if blobContent, ok := mcp.AsBlobResourceContents(item); ok {
			contents = append(contents, ResourceContent{
				URI:      blobContent.URI,
				MimeType: blobContent.MIMEType,
				Blob:     blobContent.Blob,
			})
		}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Inspect the wrapped cause (errors.Unwrap / %w suffix) for the real server or network error
  2. Verify the resource URI against the server's advertised resources list
  3. Reconnect: recreate the client via GetOrCreateClient if checkErrorAndDisconnectIfNeeded marked it disconnected
  4. Check OAuth token state for the principal/service; re-authorize if refresh failed

Example fix

// before
c, err := client.ReadResource(ctx, req)
if err != nil { panic(err) }
// after
c, err := client.ReadResource(ctx, req)
if err != nil {
    var reauth *OAuthReauthorizationRequiredError
    if errors.As(err, &reauth) { /* trigger re-auth flow */ }
    return nil, fmt.Errorf("failed to read resource: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

resources, err := client.ListResources(ctx)
if err != nil { return err }
if !uriInList(req.URI, resources) { return fmt.Errorf("resource %s not offered by service", req.URI) }

Type guard

func isResourceReadFailure(err error) bool { return err != nil && strings.Contains(err.Error(), "failed to read resource:") }

Try / catch

contents, err := client.ReadResource(ctx, req)
if err != nil {
    var reauth *mcp.OAuthReauthorizationRequiredError
    if errors.As(err, &reauth) { /* trigger re-auth */ }
    return fmt.Errorf("resource read failed: %w", err)
}

Prevention

When it happens

Trigger: Calling MCPClient.ReadResource(ctx, req) when the server is unreachable, the resource URI does not exist or is rejected, the session died, or OAuth token handling inside oauthCall failed.

Common situations: Requesting a resource URI the server doesn't expose; server restarted so the SSE session is stale; permission denied server-side; token expired and refresh failed.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/4a57a32fcc06c53c. Report an issue: GitHub.