mastra-ai/mastra · error · ProtocolError

Resource not found: ${uri}

Error message

Resource not found: ${uri}

What it means

After successfully listing resources, the server finds the resource whose `uri` matches the read request. If no entry matches, it logs a warning and throws an MCP ProtocolError with code InvalidParams and message `Resource not found: <uri>`.

Source

Thrown at packages/mcp/src/server/server.ts:1313

      });
    }

    // Read resource handler
    if (capturedResourceOptions.getResourceContent) {
      serverInstance.setRequestHandler('resources/read', async (request, ctx) => {
        const startTime = Date.now();
        const uri = request.params.uri;
        this.logger.debug('Handling ReadResource request', { uri });

        // Resolve the resource list for the current caller's `extra` on every request
        // rather than from a shared cache, so URI resolution respects per-caller auth.
        const resources = await capturedResourceOptions.listResources?.({ extra: toMCPRequestHandlerExtra(ctx) });
        if (!resources) throw new Error('Failed to load resources');
        const resource = resources.find(r => r.uri === uri);

        if (!resource) {
          this.logger.warn('Unknown resource URI requested', { uri });
          throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource not found: ${uri}`);
        }

        try {
          const resourcesOrResourceContent = await capturedResourceOptions.getResourceContent({
            uri,
            extra: toMCPRequestHandlerExtra(ctx),
          });
          const resourcesContent = Array.isArray(resourcesOrResourceContent)
            ? resourcesOrResourceContent
            : [resourcesOrResourceContent];
          // Preserve the resource's `_meta` on the read contents. MCP Apps hosts
          // read the UI CSP (connectDomains) from `contents[]._meta.ui.csp`, so
          // dropping it here silently ignores appResources CSP config.
          const resourceMeta = resource._meta ? { _meta: resource._meta } : {};
          const contents: (TextResourceContents | BlobResourceContents)[] = resourcesContent.map(resourceContent => {
            if ('text' in resourceContent && resourceContent.text !== undefined) {
              return {
                uri: resource.uri,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Call resources/list as the same caller and confirm the URI appears; use that exact string.
  2. Check listResources auth logic — the resource may be intentionally hidden for this caller's `extra`.
  3. Compare URIs byte-for-byte (scheme, slashes, query, case) between the client request and the registered resource.

Example fix

// before
await client.readResource({ uri: 'config://app/settings/' });
// after: use the exact registered URI
await client.readResource({ uri: 'config://app/settings' });
Defensive patterns

Strategy: validation

Validate before calling

const { resources } = await client.listResources(); if (!resources.find(r => r.uri === uri)) throw new Error(`unknown resource uri: ${uri}`);

Type guard

function resourceExists(uri: string, resources: { uri: string }[]): resources is { uri: string }[] { return resources.some(r => r.uri === uri); }

Try / catch

try { return await client.readResource({ uri }); } catch (e) { if (String(e?.message).startsWith('Resource not found')) { const { resources } = await client.listResources(); const match = resources.find(r => r.uri === uri); if (!match) logger.warn(`uri ${uri} not in current resource list`); } throw e; }

Prevention

When it happens

Trigger: A `resources/read` for a URI that the server's `listResources` did not return — the URI is unknown, was filtered out by per-caller auth in listResources, or contains a typo/case mismatch.

Common situations: Clients caching a resource list from before the resource was removed, auth-scoped listResources hiding the resource from the current caller, or URI formatting differences (trailing slash, scheme case).

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/0039ac022e8fb2c5. Report an issue: GitHub.