can1357/oh-my-pi · error
No MCP server has resource "${uri}". Available resources: $
Error message
No MCP server has resource "${uri}".
Available resources:
${formatAvailableResources(mcpManager)} What it means
After extracting the wrapped resource URI from the mcp:// URL, the handler searches all connected servers' discovered resources (literal URIs, then URI templates, refreshed once via ensureServerResources). If no server advertises a matching resource or template, it throws with the requested URI and a formatted list of every resource actually available so the caller can self-correct.
Source
Thrown at packages/coding-agent/src/internal-urls/mcp-protocol.ts:133
*/
export class McpProtocolHandler implements ProtocolHandler {
readonly scheme = "mcp";
readonly immutable = true;
async resolve(url: InternalUrl): Promise<InternalResource> {
const mcpManager = MCPManager.instance();
if (!mcpManager) {
throw new Error("No MCP manager available. MCP servers may not be configured.");
}
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) {View on GitHub (pinned to 9690622007)
Solutions
- Copy a URI exactly from the 'Available resources' list embedded in the error message (match is exact string equality for literal URIs).
- Reconnect/refresh the MCP server so ensureServerResources picks up newly added resources, then retry.
- If the resource is server-generated, run the producing tool/flow first so it appears in the resource list.
- If it should be a dynamic resource, check the server's uriTemplate and build a URI matching that template.
Example fix
// before
read("mcp://notes/roapmap"); // typo — no such resource
// after (URI taken verbatim from the error's Available resources list)
read("mcp://notes/roadmap"); Defensive patterns
Strategy: try-catch
Try / catch
try {
return await handler.resolve(parseInternalUrl(input));
} catch (e) {
if (e instanceof Error && e.message.startsWith("No MCP server has resource")) {
const available = e.message.split("Available resources:\n")[1] ?? "(none)";
console.warn(`Unknown MCP resource; available:\n${available}`);
return null;
}
throw e;
} Prevention
- Only cite URIs copied verbatim from MCP resource listings — literal matching is exact string equality.
- Re-list resources after reconnecting a server before referencing new resources.
- Run the server tool/flow that materializes dynamic resources before reading them.
- Check URI templates and fill template parameters exactly.
When it happens
Trigger: Resolving an mcp:// URL whose inner URI does not exactly match any resource URI and does not match any server's URI template — a typo'd URI, a resource that was removed/renamed on the server, or a server that exposes the resource only after a tool call the client never made.
Common situations: Hard-coded mcp:// links from old session notes pointing at resources the server no longer lists; referencing a resource before the server finishes discovery; wrong server connected (URI exists on a server that isn't in config); template parameters filled incorrectly so no template matches.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ENXIO
- Refusing to download onto a non-regular file: ${absolutePath
- Refusing to download onto a file with ${stat.nlink} hard lin
- Tool "write" not available: this session cannot download res
- (dynamic write-policy refusal message: throw new Error(refus
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6b06742920da92c9.
Report an issue: GitHub.