can1357/oh-my-pi · error

MCP resource read error: ${message}

Error message

MCP resource read error: ${message}

What it means

The handler found a server advertising the requested URI and called MCPManager.readServerResource, but the underlying MCP read request threw. The handler wraps the original error message in 'MCP resource read error: ...' so callers see which resource-read step failed while retaining the transport/protocol cause.

Source

Thrown at packages/coding-agent/src/internal-urls/mcp-protocol.ts:143

		const uri = extractResourceUri(url);
		let targetServer = resolveTargetServer(mcpManager, uri);
		if (!targetServer) {
			await Promise.allSettled(mcpManager.getConnectedServers().map(name => mcpManager.ensureServerResources(name)));
			targetServer = resolveTargetServer(mcpManager, uri);
		}
		if (!targetServer) {
			throw new Error(
				`No MCP server has resource "${uri}".\n\nAvailable resources:\n${formatAvailableResources(mcpManager)}`,
			);
		}

		let result: MCPResourceReadResult | undefined;
		try {
			result = await mcpManager.readServerResource(targetServer, uri);
		} catch (error) {
			const message = error instanceof Error ? error.message : String(error);
			throw new Error(`MCP resource read error: ${message}`);
		}

		if (!result) {
			throw new Error(`Server "${targetServer}" returned no content for "${uri}".`);
		}

		const textParts: string[] = [];
		for (const item of result.contents) {
			if (item.text !== undefined && item.text !== null) {
				textParts.push(item.text);
			} else if (item.blob) {
				textParts.push(`[Binary content: ${item.mimeType ?? "unknown"}, base64 length ${item.blob.length}]`);
			}
		}

		const content = textParts.length > 0 ? textParts.join("\n---\n") : "(empty resource)";
		return {
			url: url.href,

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the wrapped inner message — it carries the actual cause; fix that (restart server, fix auth, repair network) and retry.
  2. Restart or redeploy the MCP server that owns the resource, then re-list resources to confirm it is healthy.
  3. Reproduce the read directly with the MCP server's own client/inspector to confirm whether it is a server-side bug to report upstream.
  4. Add retry with backoff around transient transport failures when issuing mcp:// reads in automation.

Example fix

// before
const res = await handler.resolve(url); // throws raw on flaky remote server
// after
try {
  const res = await handler.resolve(url);
} catch (e) {
  if (/read error: .*(timeout|ECONNRESET)/i.test(e.message)) {
    await restartMcpServer(targetServer);
    return handler.resolve(url); // one retry after recovery
  }
  throw e;
}
Defensive patterns

Strategy: retry

Try / catch

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    return await handler.resolve(url);
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    if (/^MCP resource read error:/.test(msg) && /timeout|ECONNRESET|EPIPE|not connected/i.test(msg)) {
      await Bun.sleep(2 ** attempt * 500);
      continue;
    }
    throw e;
  }
}
throw new Error(`MCP read failed after retries: ${url.href}`);

Prevention

When it happens

Trigger: The target MCP server rejects or fails the resources/read request: server crash or restart mid-call, transport (stdio/HTTP) failure, server-side permission error, malformed resource on the server, or timeout in the underlying SDK call.

Common situations: MCP server process died (bad dependency, OOM) between listing and reading; server requires auth that expired; server bug when serializing that particular resource; network drop for a remote (SSE/streamable-HTTP) MCP server.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/72adbdc11477aaf8. Report an issue: GitHub.