{"record":{"id":"682fe06f9e629294","repo":"mastra-ai/mastra","slug":"app-resource-not-found-uri","errorCode":null,"errorMessage":"App resource not found: ${uri}","messagePattern":"App resource not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/server/server.ts","lineNumber":877,"sourceCode":"\n      resolvedAppResources.set(uri, { resource, html });\n    }\n\n    if (resolvedAppResources.size === 0) {\n      return userResources;\n    }\n\n    // Build merged resource callbacks\n    const appListResources = async () => {\n      return Array.from(resolvedAppResources.values()).map(r => r.resource);\n    };\n\n    const appGetResourceContent = async ({ uri }: { uri: string }) => {\n      const appRes = resolvedAppResources.get(uri);\n      if (appRes) {\n        return { text: appRes.html };\n      }\n      throw new Error(`App resource not found: ${uri}`);\n    };\n\n    if (!userResources) {\n      return {\n        listResources: appListResources,\n        getResourceContent: appGetResourceContent,\n      };\n    }\n\n    // Merge: user resources take precedence, app resources are appended\n    return {\n      listResources: async ({ extra }) => {\n        const userResourceList = await userResources.listResources({ extra });\n        const appResourceList = await appListResources();\n        // Filter out app resources that conflict with user-defined ones\n        const userUris = new Set(userResourceList.map(r => r.uri));\n        const nonConflicting = appResourceList.filter(r => !userUris.has(r.uri));\n        return [...userResourceList, ...nonConflicting];","sourceCodeStart":859,"sourceCodeEnd":895,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp/src/server/server.ts#L859-L895","documentation":"When an MCP server has app resources but no user-defined resources, `appGetResourceContent` is registered as the sole resource-content handler. It looks the URI up in `resolvedAppResources` and throws a plain Error when the requested URI is not one of the server's registered app resources.","triggerScenarios":"A `resources/read` request whose `uri` is not present in the `resolvedAppResources` map (the URI was never registered via app resource definitions, or was removed/unresolved).","commonSituations":"Client requesting a stale or hardcoded app-resource URI, a typo in the URI, or the app resource failing to register so the map is empty while the client still asks for it.","solutions":["Call `server.listResources()` (or the resources/list endpoint) and use one of the returned URIs exactly.","Verify the app resource was registered before the read — check registration code and any async resolution that populates resolvedAppResources.","If you also need custom resources, pass `resources` options so userResources handlers handle those URIs instead of the app-only handler."],"exampleFix":"// before: reading a guessed URI\nawait client.readResource({ uri: 'ui://my-app/panel' });\n// after: use a URI from resources/list\nconst { resources } = await client.listResources();\nawait client.readResource({ uri: resources[0].uri });","handlingStrategy":"validation","validationCode":"const { resources } = await client.listResources(); if (!resources.some(r => r.uri === uri)) throw new Error(`URI ${uri} is not an available app resource`);","typeGuard":"function isKnownAppResource(uri: string, known: { uri: string }[]): boolean { return known.some(r => r.uri === uri); }","tryCatchPattern":"try { return await client.readResource({ uri }); } catch (e) { if (String(e?.message).startsWith('App resource not found')) { const { resources } = await client.listResources(); return await client.readResource({ uri: resources[0].uri }); } throw e; }","preventionTips":["Always discover app resource URIs via resources/list instead of hardcoding them.","Confirm app resources register successfully at server startup before clients connect.","Log the full resource list when a read fails to spot stale URIs."],"tags":["mcp","resources","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}