mastra-ai/mastra · error · Error
The "extra" key is now nested under "mcp.extra" in tool…
Error message
The "extra" key is now nested under "mcp.extra" in tool arguments
What it means
Companion to the `elicitation` migration guard: accessing the top-level `extra` key in tool arguments now throws with a pointer to the new location, `mcp.extra`. The throwing getter exists solely to surface the rename to developers instead of silently returning undefined.
Solutions
- Access request/session data via `mcp.extra` instead of the top-level `extra` argument.
- Update destructured parameters to pull `extra` from the nested `mcp` object.
- Grep tools for `extra.` and `extra}` usages and migrate them to `mcp.extra`.
Example fix
// before
execute: async (args, { extra }) => console.log(extra.sessionId)
// after
execute: async (args, mcp) => console.log(mcp.extra.sessionId) Defensive patterns
Strategy: type-guard
Validate before calling
// static check before deploy grep -rn "\bextra\b" src/tools/ | grep -v "mcp.extra" && echo 'migrate to mcp.extra'
Type guard
function getExtra(mcp: unknown): McpExtra | undefined { return !!mcp && typeof mcp === 'object' && 'extra' in mcp ? (mcp as any).extra : undefined; } Try / catch
try { return await tool.execute(args, mcpOptions); } catch (e) { if (String(e?.message).includes('mcp.extra')) { throw new Error('Tool uses deprecated top-level extra; migrate to mcp.extra'); } throw e; } Prevention
- Access request/session metadata exclusively via mcp.extra.
- Update copied sample tools from older tutorials to the nested API.
- Type the execute options parameter so unknown top-level keys are rejected at compile time.
When it happens
Trigger: During a `tools/call`, the tool's execute function accesses `context.extra` (e.g. `extra.requestInfo`, `extra.sessionId`, or request metadata) on the proxied MCP context.
Common situations: Tools that read HTTP request info, auth context, or per-session data via `extra` written before the `mcp.extra` nesting was introduced.
Related errors
- The "elicitation" key is now nested under "mcp.elicitation"…
- Invalid structured content for tool
- MastraFactory: 'sandbox' is now a callback, not an options…
- MCP_CLIENT_ON_LIST_CHANGED_TOOLS_FAILED
- MCP_SERVER_TOOL_EXECUTE_PREPARATION_FAILED
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/527642d0be0565ab.
Report an issue: GitHub.
Appendix: source
Thrown at packages/mcp/src/server/server.ts:1141
};
const mcpOptions: MastraToolInvocationOptions = {
messages: [],
toolCallId: '',
requestContext: proxiedContext,
// Pass MCP-specific context through the mcp property
mcp: {
elicitation: sessionElicitation,
extra,
log: sessionLog,
progress: sessionProgress,
},
// @ts-expect-error this is to let people know that the elicitation and extra keys are now nested under mcp.elicitation and mcp.extra in tool arguments
get elicitation() {
throw new Error(`The "elicitation" key is now nested under "mcp.elicitation" in tool arguments`);
},
get extra() {
throw new Error(`The "extra" key is now nested under "mcp.extra" in tool arguments`);
},
};
await this.enforceToolExecutionFGA(request.params.name, proxiedContext);
const result = await tool.execute(validation?.value ?? request.params.arguments ?? {}, mcpOptions);
const duration = Date.now() - startTime;
// Check if the tool builder returned a validation error (e.g. input failed Zod validation
// after passing the JSON Schema first-pass validation above)
if (isValidationError(result)) {
this.logger.warn(`CallTool: Tool '${request.params.name}' returned a validation error in ${duration}ms.`, {
error: result.message,
});
return {
content: [{ type: 'text', text: result.message }],
isError: true,View on GitHub (pinned to 75dd419e61)