vercel/ai · warning · Error
Invalid resources/read params
Error message
Invalid resources/read params
What it means
The bridge validates `resources/read` requests from the MCP App iframe and requires a `uri` string param. This error is thrown when params are not a JSON object or `params.uri` is missing or not a string. It prevents the host's readResource callback from being called with malformed data.
Source
Thrown at packages/react/src/mcp-apps/bridge.ts:71
* Validates the params for app-initiated `tools/call` requests.
*/
function assertToolCallParams(params: unknown): MCPAppToolCallParams {
if (!isJSONObject(params) || typeof params.name !== 'string') {
throw new Error('Invalid tools/call params');
}
return {
name: params.name,
arguments: isJSONObject(params.arguments) ? params.arguments : undefined,
};
}
/**
* Validates `resources/read` params and limits reads to `ui://` app resources.
*/
function assertResourceReadParams(params: unknown): { uri: string } {
if (!isJSONObject(params) || typeof params.uri !== 'string') {
throw new Error('Invalid resources/read params');
}
if (!params.uri.startsWith('ui://')) {
throw new Error(
`resources/read is limited to ui:// resources: ${params.uri}`,
);
}
return { uri: params.uri };
}
/**
* Validates `ui/open-link` params and allows only `https:`/`http:`/`mailto:`
* URLs.
*/
function assertOpenLinkParams(params: unknown): { url: string } {
if (!isJSONObject(params) || typeof params.url !== 'string') {
throw new Error('Invalid ui/open-link params');
}
View on GitHub (pinned to 69428b1f8b)
Solutions
- Ensure the iframe sends `{ method: 'resources/read', params: { uri: '<string>' } }`.
- Check for a `uri` vs `url` key typo in the app's request.
- Inspect the failing request in the host `onError` callback to see what the iframe actually sent.
- Update the app-side MCP SDK to a version that conforms to the MCP Apps resources/read schema.
Example fix
// before
client.readResource({ url: 'ui://resource' })
// after
client.readResource({ uri: 'ui://resource' }) Defensive patterns
Strategy: validation
Validate before calling
function isValidResourceReadParams(params: unknown): boolean {
return (
typeof params === 'object' && params !== null && !Array.isArray(params) &&
typeof (params as any).uri === 'string'
);
}
// before calling resources/read:
if (!isValidResourceReadParams({ uri })) throw new Error('resources/read requires a string uri'); Type guard
function isResourceReadParams(v: unknown): v is { uri: string } {
return typeof v === 'object' && v !== null && !Array.isArray(v) &&
typeof (v as any).uri === 'string';
} Try / catch
try {
const result = await readResource({ uri });
} catch (error) {
if (error instanceof Error && error.message === 'Invalid resources/read params') {
console.error('resources/read params must include a string uri field');
}
} Prevention
- Use the `uri` key (not `url`) with a string value.
- Validate params shape app-side before posting the JSON-RPC request.
- Keep the iframe app on a spec-conformant MCP SDK version.
When it happens
Trigger: The iframe sends `resources/read` with params missing entirely, with `params` not an object, or with a non-string/absent `uri` (e.g. `{ uri: 123 }` or `{}`).
Common situations: A custom app iframe constructed by hand; a spec-noncompliant SDK inside the iframe; passing a resource object instead of its uri string; typo like `url` instead of `uri`.
Related errors
- Invalid tools/call params
- Invalid ui/open-link params
- Invalid ui/open-link url: ${params.url}
- Invalid ui/request-display-mode params
- Invalid MCP App resource URI: ${JSON.stringify(resourceUri)}
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/27621396dfef3e98.
Report an issue: GitHub.