{"record":{"id":"f0fe1164039943eb","repo":"mastra-ai/mastra","slug":"resource-uri-returned-content-with-neither-te","errorCode":null,"errorMessage":"Resource '${uri}' returned content with neither text nor blob","messagePattern":"Resource '(.+?)' returned content with neither text nor blob","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/server/server.ts","lineNumber":1340,"sourceCode":"            ? resourcesOrResourceContent\n            : [resourcesOrResourceContent];\n          // Preserve the resource's `_meta` on the read contents. MCP Apps hosts\n          // read the UI CSP (connectDomains) from `contents[]._meta.ui.csp`, so\n          // dropping it here silently ignores appResources CSP config.\n          const resourceMeta = resource._meta ? { _meta: resource._meta } : {};\n          const contents: (TextResourceContents | BlobResourceContents)[] = resourcesContent.map(resourceContent => {\n            if ('text' in resourceContent && resourceContent.text !== undefined) {\n              return {\n                uri: resource.uri,\n                mimeType: resource.mimeType,\n                ...resourceMeta,\n                text: resourceContent.text,\n              } as TextResourceContents;\n            }\n\n            const blob = (resourceContent as { blob?: string }).blob;\n            if (blob === undefined) {\n              throw new Error(`Resource '${uri}' returned content with neither text nor blob`);\n            }\n\n            return {\n              uri: resource.uri,\n              mimeType: resource.mimeType,\n              ...resourceMeta,\n              blob,\n            } as BlobResourceContents;\n          });\n          const duration = Date.now() - startTime;\n          this.logger.info('Resource read successfully', { uri, duration });\n          return {\n            contents,\n          };\n        } catch (error) {\n          const duration = Date.now() - startTime;\n          this.logger.error('Failed to get content for resource', { uri, duration, error });\n          throw error;","sourceCodeStart":1322,"sourceCodeEnd":1358,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp/src/server/server.ts#L1322-L1358","documentation":"Resource content returned by `getResourceContent` must include either a `text` or a `blob` field per the MCP resource-contents shape. If neither is present after checking `text`, the server throws this Error because it cannot construct valid ResourceContents for the client.","triggerScenarios":"Your `getResourceContent` callback returns an object lacking both `text` and `blob` — e.g. `{}` or an object with only `uri`/`mimeType`, or a field name typo like `content` instead of `text`.","commonSituations":"Wrapping raw file/binary data under a custom key, returning metadata-only objects, or returning null-coerced content from a storage layer without converting to base64 blob.","solutions":["Return `{ text: '...' }` for textual content or `{ blob: base64String }` for binary content from getResourceContent.","If the data is binary, base64-encode it and pass it as `blob` with an appropriate mimeType.","Add a sanity check/test asserting every resource content result has text or blob before serving."],"exampleFix":"// before\nreturn { uri, mimeType: 'image/png', data: buffer };\n// after\nreturn { uri, mimeType: 'image/png', blob: buffer.toString('base64') };","handlingStrategy":"type-guard","validationCode":"const content = await getResourceContent({ uri }); if (!('text' in content) && !('blob' in content)) throw new Error('getResourceContent must return text or blob');","typeGuard":"function hasValidContent(c: unknown): c is { text?: string; blob?: string } { const o = c as any; return typeof o?.text === 'string' || typeof o?.blob === 'string'; }","tryCatchPattern":"try { return await client.readResource({ uri }); } catch (e) { if (String(e?.message).includes('neither text nor blob')) { logger.error('server getResourceContent returned invalid shape for ' + uri); } throw e; }","preventionTips":["Return `{ text }` for strings and `{ blob: base64 }` for binaries — no custom keys.","Type getResourceContent's return as MCP ResourceContents so missing text/blob fails typecheck.","Test every registered resource's content shape at startup."],"tags":["mcp","resources","payload-shape"],"backgroundTag":"invalid-resource-content","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}